顺序流 stream()
并行流 parallelStream()
collect
快速创建List
public class User {
public User(String name, String age, int height) {
this.name = name;
this.age = age;
this.height = height;
}
private String name;
private String age;
private int height;
// setter、getter方法我就不写了
}
// 创建三个user
User user1 = new User("111", "18", 180);
User user2 = new User("222", "18", 175);
User user3 = new User("333", "19", 170);
(1)、new一个list
List<User> userList = new ArrayList<>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
(2)、Stream流:创建动态list,可以添加元素
// stream流,创建的是动态数组,可以添加元素
List<User> userList =
Stream.of(user1, user2, user3).collect(Collectors.toList());
备注:创建一个固定长度的list:Arrays.asList(…args)返回一个list(本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素)
map
可以使用map方法把对象中的某个属性取出后,重新(加工)组成新的列表。
取对象的某一列
取出list中所有user的name属性放到一个新的list中:
// Stream流
List<String> userNameList =
userList.stream().map(User::getName).collect(Collectors.toList());
filter
返回由与此给定谓词匹配的此流的元素组成的流。
筛选出userList中name不为空的user
// 获取userName不为空的user的List
List<User> userList = userList.stream()
.filter(user-> user.getName() != null)
.collect(Collectors.toList());
/**
* IO流用于读写,Stream流用于处理数组和集合数据,解决传统集合遍历
*/
Set<String> set = new TreeSet<>();
set.add("张**");
set.add("wang**");
set.add("张*1");
set.add("张wagn**");
set.add("kak**");
set.add("lili**");
set.add("张**");
//forEach
set.stream().filter(name -> name.startsWith("张"))
.filter(name -> name.length() == 3)
.forEach(name -> System.out.println(name));
groupingBy 分组
userList中的user根据年龄分组
Map<String, List<User>> map =userList.stream()
.collect( Collectors.groupingBy(User::getAge, Collectors.toList()));
int、double、long:求和
// int、double、long:
double max = userList.stream().mapToDouble(User::getHeight).sum();
Map、List互转
1)list转map:
stream流:
用Collectors的toMap方法转换List,一般会遇到两个问题。
(1)转换map,key重复问题;
代码中使用(key1,key2)->key2表达式可以解决此类问题,如果出现重复的key就使用key2覆盖前面的key1,也可以定义成(key1,key2)->key1,保留key1,根据自己的业务场景来调整。
(2)空指针异常,即转为map的value是null。这个可以用filter过滤;
Map<String, User> userMap=
userList.stream()
.collect(Collectors.toMap(
User::getName, Function.identity(),(key1, key2)->key2)
);
2)map转list:
List<User> userList =
userMap.entrySet().stream()
.map(e ->e.getValue())
.collect(Collectors.toList());
//初始化list
List<Entity> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
Entity object = new Entity();
object.setId(i);
object.setUsername(String.valueOf(i >>> 1));
log.info("i:{}, i >>> 1:{}", i, i >>> 1);
list.add(object);
}
//初始化map
Map<Integer, String> map = new TreeMap<>();
if (CollectionUtil.isNotEmpty(list)) {
map = list.stream().collect(Collectors.toMap(Entity::getId, Entity::getUsername,
(t1, t2) -> t2));
log.info("map:{}", map);
}
//map输出
if (null != map) {
Map<Integer, String> finalMap = map;
map.keySet().forEach(item -> {
System.out.println("key = " + item + ", value = " + finalMap.get(item));
});
Set<Integer> set = map.keySet();
System.out.println(set);
}
anyMatch() 判断的条件里,任意一个元素成功,返回true
// 判断是否有height > 175
userList.stream().anyMatch(user -> user.getHeight() > 175);
allMatch():判断条件里的元素,所有的都是,返回true
//判断是否全部height > 175的
userList.stream().allMatch(user -> user.getHeight() > 175);
noneMatch():与allMatch相反,判断条件里的元素,所有的都不是,返回true
userList.stream().noneMatch(user -> user.getHeight() > 175);
count:求取目标和
userList.stream().filter(user -> user.getHeight() > 175).count();
合并List
1)、合并多个一维List
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
List<Integer> list3 = Arrays.asList(7, 8, 9);
List<Integer> mergedList = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());
System.out.println(mergedList);// [1, 2, 3, 4, 5, 6, 7, 8, 9]
2)、合并嵌套List:
List<String> list1 = Arrays.asList("张三", "李四", "王二麻子");
List<String> list2 = Arrays.asList("111", "222", "333");
// 合并前
List<List<String>> lists = Arrays.asList(list1, list2);
System.out.println(lists);
// 合并后
List<String> mergedList = lists.stream().flatMap(Collection::stream).collect(Collectors.toList());
System.out.println(mergedList);
findAny和findFirst
找到列表中任一符合条件的对象,无序的,只要满足就返回。注意如果使用stream方法,findAny会一直返回第一个对象,因为stream是串行有序的;如果使用parallelStream流,返回的就是任一一个了。
findFirst,顾名思义返回第一个满足条件的对象。
Student s1 = new Student("AB-1", 10);
Student s2 = new Student("CD-2", 12);
Student s3 = new Student("EF-3", 15);
Student s4 = new Student("GH-4", 10);
List<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
Student student1 = list.stream().filter(s -> s.getAge() > 10).findAny().get();
Student student2 = list.parallelStream().filter(s -> s.getAge() > 10).findAny().get();
Student student3 = list.stream().filter(s -> s.getAge() > 10).findFirst().get();
System.out.println(student1);//{"name":"CD-2","age":12}
System.out.println(student2);//{"name":"EF-3","age":15}
System.out.println(student3);//{"name":"CD-2","age":12}
parallelStream
当数据量大时,采用parallelStream,会把数据分成多个小任务,多线程处理数据,提高处理速度。
是否使用parallelStream需要考虑几个方面:
数据是否足够大;任务之间是否独立;输出结果是否需要有序。
mapToInt
mapToLong
mapToDouble
flatMap
flatMapToInt
flatMapToLong
flatMapToDouble
distinct
sorted 可以对数据进行排序,多个字段亦可。
Student s1 = new Student("AB-1", 10);
Student s2 = new Student("CD-2", 12);
Student s3 = new Student("EF-3", 15);
Student s4 = new Student("GH-4", 18);
Student s5 = new Student("GH-4", 14);
List<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
List<Student> students = list.stream()
.sorted(Comparator.comparing(Student::getName).
thenComparing(Student::getAge)).
collect(Collectors.toList());
System.out.println(students);
//[{"name":"AB-1","age":10},
// {"name":"CD-2","age":12},
// {"name":"EF-3","age":15},
// {"name":"GH-4","age":14},
// {"name":"GH-4","age":18}]
reduce对数据进行归纳
Student s1 = new Student("AB-1", 10);
Student s2 = new Student("CD-2", 12);
Student s3 = new Student("EF-3", 15);
List<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
int total = list.stream()
.map(Student::getAge).reduce(0, Integer::sum);
System.out.println(total);//37
sorted
peek
limit
skip
forEach
forEachOrdered
toArray
toArray
reduce
min
max
builder
empty
of
iterate
generate
concat:用于把流组合到一起如果有两个流,希望合并成为一个流
//创建一个Stream流
Stream<String> stream1 = Stream.of("张三丰", "张翠山", "赵敏", "周芷若", "张无忌");
//获取一个Stream流
String[] arr = {"喜羊羊","美羊羊","灰太狼","懒羊羊","红太狼"};
Stream<String> stream2 = Stream.of(arr);
//把以上两个流组合为一个流
Stream<String> concat = Stream.concat(stream1, stream2);
//遍历concat流
concat.forEach(name-> System.out.println(name));
/**
张三丰
张翠山
赵敏
周芷若
张无忌
喜羊羊
美羊羊
灰太狼
懒羊羊
红太狼
**/