玩转集合的遍历,筛选、聚合、映射
三、使用
1、遍历(foreach/find/match)

1.1、遍历 foreach
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);// 遍历输出符合要求的元素list.stream().filter((x) -> x % 2 == 0).forEach(System.out::println);// 匹配任意一个(适用于并行流)Optional<Integer> any = list.parallelStream().filter(x -> x % 2 == 0).findAny();System.out.println("符合要求的任意一个元素:" + any.get());// 判断是否包含符合条件的元素
1.2、是否匹配所有元素 allMatch
allMatch用于判断流中的所有元素是否都满足指定条件,
这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);boolean isMatch = list.stream().allMatch(x -> x % 2 == 0);System.out.println("是否匹配所有元素:"+isMatch);
1.3、是否未匹配所有元素:noneMatch
noneMatch与allMatch恰恰相反,它用于判断流中的所有元素是否都不满足指定条件:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);boolean isMatch = list.stream().noneMatch(x -> x % 2 == 0);System.out.println("是否匹配所有元素:"+isMatch);
1.4、是否匹配任一元素:anyMatch
anyMatch用于判断流中是否存在至少一个元素满足指定的条件,
这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类型。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);boolean isMatch = list.stream().anyMatch(x -> x % 2 == 0);System.out.println("是否存在符合条件的元素:"+isMatch);
1.5、获取任一元素findAny
findAny能够从流中随便选一个元素出来,它返回一个Optional类型的元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);// 匹配任意一个(适用于并行流)Optional<Integer> any = list.parallelStream().filter(x -> x % 2 == 0).findAny();System.out.println("符合要求的任意一个元素:" + any.get());
1.6、获取第一个元素
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
// 匹配符合要求的第一个元素
Optional<Integer> first = list.stream().filter((x) -> x % 2 == 0).findFirst();
System.out.println("符合要求的第一个元素:" + first.get());
2、筛选(filter)
筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。
filter 函数接收一个Lambda表达式作为参数,该表达式返回boolean,在执行过程中,流将元素逐一输送给filter,并筛选出执行结果为true的元素。
案例一:筛选出list集合中的偶数,并打印出来
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
Stream<Integer> stream = list.stream();
// 遍历输出符合要求的元素
stream.filter((x) -> x % 2 == 0).forEach(System.out::println);
案例二: 筛选员工中工资高于8000的人,并形成新的集合。
形成新集合依赖collect(收集)
List<Person> personList = new ArrayList<>();
personList.add(new Person("Tom", 8900, 21, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 41, "female", "Washington"));
personList.add(new Person("Anni", 8200, 11, "female", "New York"));
personList.add(new Person("Owen", 9500, 26, "male", "New York"));
personList.add(new Person("Alisa", 7900, 19, "female", "New York"));
List<String> filterList = personList.stream().filter(x -> x.getSalary() > 8000).map(Person::getName)
.collect(Collectors.toList());
System.out.print("高于8000的员工姓名:" + filterList);
3、聚合(max/min/count)
max/min/count Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。
案例一:获取**String**集合中最长的元素。
List<String> list1 = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");
Optional<String> max = list1.stream().max(Comparator.comparing(String::length));
Optional<String> min = list1.stream().min(Comparator.comparing(String::length));
System.out.println("最长的字符串:" + max.get());
System.out.println("最短的字符串:" + min.get());
运行结果:
案例二:获取**Integer**集合中的最大值。
List<Integer> list2 = Arrays.asList(7, 6, 9, 4, 11, 6);
Optional<Integer> max1 = list2.stream().max(Integer::compareTo);
// 自定义排序
Optional<Integer> max2 = list2.stream().max(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println("自然排序的最大值:" + max1.get());
运行结果:
案例三:获取员工工资最高的人。
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
Optional<Person> max3 = personList.stream().max(Comparator.comparingInt(Person::getSalary));
System.out.println("员工工资最大值:" + max3.get().getSalary());
运行结果:
案例四:计算**Integer**集合中大于6的元素的个数。
List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
long count = list.stream().filter(x -> x > 6).count();
System.out.println("list中大于6的元素个数:" + count);
运行结果:
4、映射(map/flatMap)
映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。
分为map和flatMap:
map:接收一个函数作为参数,该函数会被应用到每个元素上,对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。
流会将每一个元素输送给map函数,并执行map中的Lambda表达式,最后将执行结果存入一个新的流中。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
**
String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);
List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println("每个元素大写:" + strList);
System.out.println("每个元素+3:" + intListNew);
案例二:将员工的薪资全部增加1000
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
// 不改变原来员工集合的方式
List<Person> personListNew = personList.stream().map(person -> {
Person personNew = new Person(person.getName(), 0, 0, null, null);
personNew.setSalary(person.getSalary() + 10000);
return personNew;
}).collect(Collectors.toList());
System.out.println("一次改动前:" + personList.get(0).getName() + "-->" + personList.get(0).getSalary());
System.out.println("一次改动后:" + personListNew.get(0).getName() + "-->" + personListNew.get(0).getSalary());
// 改变原来员工集合的方式
List<Person> personListNew2 = personList.stream().map(person -> {
person.setSalary(person.getSalary() + 10000);
return person;
}).collect(Collectors.toList());
System.out.println("二次改动前:" + personList.get(0).getName() + "-->" + personListNew.get(0).getSalary());
System.out.println("二次改动后:" + personListNew2.get(0).getName() + "-->" + personListNew.get(0).getSalary());
不改变原数据,就是在函数之中进行新创建对象,使用新创建的对象进行赋值
案例三:将两个字符数组合并成一个新的字符数组
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> listNew = list.stream().flatMap(s -> {
// 将每个元素转换成一个stream
String[] split = s.split(",");
return Arrays.stream(split);
}).collect(Collectors.toList());
System.out.println("处理前的集合:" + list);
System.out.println("处理后的集合:" + listNew);
案例四:列出List中各不相同的单词,List集合如下
List<String> list = new ArrayList<String>();
list.add("I am a boy");
list.add("I love the girl");
list.add("But the girl loves another girl");
//实现思路如下:、
//1、将list变成流对象
//2、对每一个流元素进行处理(按照空格进行分词)
//3、将每一个处理完的流元素集合起来转换为一个待处理的新流(使用flatMap)
//4、对新流进行去重操作
//5、输出流
list.stream()
.map(line->line.split(" "))
.flatMap(Arrays::stream)
.distinct()
.collect(toList());
附录:
[

