1 Stream 介绍:
流是java API中的新的成员,它可以让你用声明式的方式处理集合,简单点说,可以看成遍历数据的一个高级点的迭代器,也可以看做一个工厂,数据处理的工厂,当然,流还天然的支持并行操作。
2 Stream 使用:
2.1 ForEach进行遍历:
ForEach对List/Set/Map 遍历:
List<User> users= new ArrayList<>();
for(int i=0 ;i<100000;i++){
StreamTest.User user = new StreamTest.User();
user.setName("test"+i);
user.setAge(i);
users.add(user);
}
users.stream().forEach(e->{
e.setName(e.getName()+" stream");
});
Set<String> sets = new HashSet<>();
sets.add("quo.1");
sets.add("quo.2");
sets.add("quo.3");
sets.add("quo.4");
sets.stream().forEach(e->{
System.out.println("e = " + e);
});
Map<String,Integer> map = new HashMap<>();
map.put("zhangsan",23);
map.put("lisi",25);
map.put("wangwu",26);
map.put("zhaoliu",27);
map.entrySet().stream().forEach(e->{
System.out.println("e.getKey() = " + e.getKey());
System.out.println("e.getValue() = " + e.getValue());
});
其中将stream() 替换为parallelStream() 可以让其进行并发处理以提高效率
注意如果需要和原有的集合数据先后顺序保持一致,需要用 forEachOrdered 来替代forEach。
2.2 使用 filter 完成对集合的过滤从而得到满足一定条的集合:
filter 对List/Set/Map 过滤:
Map<String,Integer> map = new HashMap<>();
map.put("zhangsan",23);
map.put("lisi",25);
map.put("wangwu",26);
map.put("zhaoliu",27);
// 得到key 值为lisi 的数据
Map<String,Integer> map1 = map.entrySet().stream().filter(e-> e.getKey().equals("lisi")).collect(Collectors.toMap((e)->e.getKey(),(e)->e.getValue()));
List<User> users= new ArrayList<>();
for(int i=0 ;i<100000;i++){
StreamTest.User user = new StreamTest.User();
user.setName("test"+i);
user.setAge(i);
users.add(user);
}
List<User> filterUsers = users.stream().filter(e-> e.getAge() >6 ).collect(Collectors.toList());
或者:
List<User> filterUsers = users.stream().filter(e-> {
boolean flag = false;
if (e.getAge()>6){
flag = true;
}
return flag;
} ).collect(Collectors.toList());
Set<String> setOne = sets.stream().filter(e-> e.equals("quo.1")).collect(Collectors.toSet());
setOne.stream().forEach(e->{
System.out.println("e = " + e);
});
同样其中将stream() 替换为parallelStream() 可以让其进行并发处理以提高效率。
2.3 map 对List/Set/Map 遍历形成新的元素并返回:
// // 返回 转换后的数据
List<Class> userClass = users.stream().map(e->{
Class classe = new Class();
classe.setClassName("math");
classe.setName(e.getName());
return classe;
}).collect(Collectors.toList());
2.4 对结果任意取一个 ,取一个集合最大值,最小值:
User userOne = users.stream().findFirst().orElse(null);
User userTwo = users.stream().findAny().orElse(null);
Optional<User> userThree = users.stream().max(Comparator.comparing(User::getAge));
if (userThree.isPresent()){
User userFour = userThree.get();
}
Optional<User> userFive = users.stream().min(Comparator.comparing(User::getAge));
if (userFive.isPresent()){
User userSix = userFive.get();
}
2.5 排序:
List<User> users1 = users.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());
users1.stream().forEach(e->{
System.out.println("e 用户= " + e);
});
2.6 分组:
Map<Integer, List<User>> grupByAge =
users.stream().collect(Collectors.groupingBy(User :: getAge));
LinkedHashMap<String,List<Mobile>> linkedHashMap =
mobileList.stream().collect(Collectors.groupingBy(Mobile::getBrand, LinkedHashMap::new,Collectors.toList()));
// 按照某个属性分组,然后抽取某个属性值组成集合
Map<Integer, List<String>> collect = users.stream().collect(Collectors.groupingBy(User::getAge,
Collectors.mapping(e->{
return e.getName();
},Collectors.toList())));
2.7 分组合并:
List<User> allUsers = grupByAge.entrySet().stream().flatMap(e->e.getValue().stream()).map(f->f).collect(Collectors.toList());
allUsers.stream().forEach(e->{
System.out.println("e 用户= " + e);
});
Stream<List<Integer>> inputStream = Stream.of(Arrays.asList(1),
Arrays.asList(2, 3), Arrays.asList(4, 5, 6));
Stream<Integer> outputStream = inputStream.FlatMap((childList) -> childList.stream());
Map<String, List<TFinanceEstimatedDictDto>> mpaData = estimatedDictService.getQuatoByType(Arrays.asList(String.valueOf(enumOne.getTypeId())), oneTypeIds);
List<TFinanceEstimatedDictDto> requiredParams = mpaData.values().stream().flatMap(Collection::stream).filter(e ->
e.getDefaultQuotaFillType() != null && EstimatedQuatoFileTypeEnum.必填.getTypeId().intValue() == e.getDefaultQuotaFillType())
.collect(Collectors.toList());
2.8 tomap:
Map<Integer, User> grupByAgeOne = users.stream().collect(Collectors.toMap(User :: getAge, Function.identity()));
// list to map 相同key 值 第二个覆盖第一个
Map<String ,User> mapUsers = users.stream().collect(Collectors.toMap(User::getName, v -> v, (v1, v2) -> v2));
mapUsers.entrySet().stream().forEach(e->{
System.out.println("e = " + e.getKey()+" value ="+e.toString());
});
// 转换大写
List<String> output = wordList.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
2.9 limit获取流中前n个元素返回。
是一个中间操作。另外这个是一个短路操作(short-circuiting)。也就是说流中的元素遍历到了第n个过后,后面的元素就不在进行遍历了
Map<Integer, User> grupByAgeOne = users.stream().limit(10).collect(Collectors.toMap(User :: getAge, Function.identity()));
2.10 peek
// 给年纪大于30岁的人,薪水提升1.5倍,并输出结果
Stream<Emp> stream = list.stream().filter(emp -> {
return emp.getAge() > 30;
}).peek(emp -> {
emp.setSalary(emp.getSalary() * 1.5);
});
println(stream);
2.11 skip 跳过前n 个元素:
List<String> lists= new ArrayList<>();
lists.add("123");
lists.add("456");
lists.add("789");
List<String> tests = lists.stream().skip(2).collect(Collectors.toList());
System.out.println(tests);
List<User> users1 = getPageResult((Collection)users,2,2);
/**
* 分页方法
*
* @param list 要分页的数据
* @param page 当前页
* @param size 每页条数
*/
public static Collection<T> getPageResult(Collection<T> list, int page, int size) {
//模拟分页效果
return list.stream().skip((page - 1) * size)
.limit(size)
.collect(Collectors.toList());
}