Java Stream


List转Map

编码过程中经常会遇到需要将List转换成Map的需求

例如文章列表(List<Article>),数据库一般只保存了作者的uid,我们在批量拿到用户信息后(List<User>),需要把User对象赋值给相应的Article,

在今天之前我一直都是手工将List<User>转换成Map<Integer, User>,其实这个过程可以使用 Stream 简单替代。

List<User> 如下:

[
User{uid=1, name='A', gender='男'}, 
User{uid=2, name='B', gender='男'}, 
User{uid=3, name='C', gender='女'},
User{uid=3, name='C', gender='女'}
]
// Function.identity() 等同于 User -> User
Map<Integer, User> mapUsers = listuser.stream().collect( Collectors.toMap( User::getUid, Function.identity()) );

上面的代码会报错,其只适用于uid不重复的情况

Exception in thread "main" java.lang.IllegalStateException: Duplicate key User{uid=3, name='C'}

修改后的代码:

// key1, key2 分别代表新旧key,二选一
Map<Integer, User> mapUsers = listuser.stream().collect( Collectors.toMap( User::getUid, Function.identity(), (key1, key2) -> key1 ) );
System.out.println(mapUsers);

输出:

{
1=User{uid=1, name='A', gender='男'}, 
2=User{uid=2, name='B', gender='男'}, 
3=User{uid=3, name='C', gender='女'}
}

获取uid -> name的映射

Map<Integer, String> mapsUidToName = listuser.stream().collect( Collectors.toMap( User::getUid, User::getName, (key1, key2) -> key1 ) );
System.out.println(mapsUidToName.toString());

// output: {1=A, 2=B, 3=C}

 

使用 groupingBy 进行分组

// 按性别分组
Map<String, List<User>> mapsGroupByGender = listuser.stream().collect( Collectors.groupingBy(User::getGender) );
System.out.println(mapsGroupByGender.toString());

输出:

{
女=[User{uid=3, name='C', gender='女'}, User{uid=3, name='C', gender='女'}], 
男=[User{uid=1, name='A', gender='男'}, User{uid=2, name='B', gender='男'}]
}

 

使用 filter 过滤

// 获取性别是男的对象
List<User> listUser2 = listuser.stream().filter( o -> "男".equals( o.getGender() ) ).collect(Collectors.toList());
System.out.println(listUser2.toString());

输出:

[
User{uid=1, name='A', gender='男'}, 
User{uid=2, name='B', gender='男'}
]

 

map方法

//  提取指定字段
List<String> listNames = listuser.stream().map(User::getName).collect(Collectors.toList());
listNames.forEach( item -> System.out.println(item) );

/*
output:
A
B
C
C
*/
// 修改成员的值
listuser.stream().map(
        item -> {
            item.setUid( item.getUid() + 100 );
            return item;
        }).collect(Collectors.toList());
System.out.println(listuser.toString());

/*
output:
[
User{uid=101, name='A', gender='男'}, 
User{uid=102, name='B', gender='男'}, 
User{uid=103, name='C', gender='女'}, 
User{uid=103, name='C', gender='女'}
]
*/