java8新增的package: stream,专门用来操作数据,不仅支持串行,还支持并行。使用起来非常方便。
提供的快捷方法有:filter,map, foreach,reduce,sorted,count,min,max,groupby,tomap,tolist等等
如果是之前,类似的数据操作,要对应的不知道要写多少个for循环。 现在只需要一行代码搞定。
写几个实例,自然就明白很多了
public class Test {
public static class Person {
public String id;
public String name;
public String age;
public Person(String id, String name) {
this.id = id;
this.name = name;
this.age = 20;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name +",age="+age+ "]";
}
}
public static void main(String args[]) throws Exception {
List<Test.Person> aa = Arrays.asList(new Test.Person("10", "a"), new Test.Person("3", "b"),
new Test.Person("2", "b"), new Test.Person("8", "c"), new Test.Person("3", "dd"),
new Test.Person("4", "d"), new Test.Person("5", ""));
// list to map
Map<String, Test.Person> result0 = aa.stream().collect(Collectors.toMap(e -> e.id, e -> e));
System.out.println(result0);
//group person by id
Map<String, List<Test.Person>> result1 = aa.stream().collect(Collectors.groupingBy(e -> e.id));
System.out.println(result1);
// group person name by id
Map<String, Set<String>> result2 = aa.stream()
.collect(Collectors.groupingBy(e -> e.id, Collectors.mapping(e -> e.name, Collectors.toSet())));
System.out.println(result2);
//excludes blank and then group person name by sorted id
Map<String, Set<String>> result3 = aa.stream()
.filter(e -> !StringUtils.isBlank(e.id) && !StringUtils.isBlank(e.name))
.sorted(( o1, o2) -> Integer.parseInt(o1.id) - Integer.parseInt(o2.id))
.collect(Collectors.groupingBy(e -> e.id, LinkedHashMap::new,
Collectors.mapping(e -> e.name, Collectors.toSet())));
System.out.println(result3);
// 来一个更复杂的: 如果有多个相同的id,多个相同的name,还可以进行两级groupby,并对第二级name进行排序
Map<String, Map<String, List<Test.Person>>> menusGroupByLevelAndParentId = allMenus.stream()
.sorted((o1, o2) -> o1.name.compareTo(o2.name))
.collect(Collectors.groupingBy(e -> e.id, Collectors
.groupingBy(e -> e.name, Collectors.toList())));
/*
对字符串集合进行字符串拼接。
虽然增加了这个方法, 方便了日常的操作。 但是这样的写法有点太累赘,不如alibaba的CollectionUtils.join(result0,",")快捷些。
*/
System.out.println(result0.keySet().stream().collect(Collectors.joining(",")));
}
}
使用注意事项
- stream对象只允许被操作一次。否则抛出异常IllegalStateException
- 如果是对io操作(文件等),需要在程序中显式关闭。 其它集合操作,jdk会自动关闭,不需要在程序中显式关闭。
小贴士:其它语言中类似的操作方式也有很多。例如js对数组的filter,map,reduce操作等。
如果是操作非常大量的数据,python的pandas library有更强大的功能。不妨一试