java8 的forEach、filter、map、distinct、sorted、peek、limit、skip、count、anyMatch、allMatch、noneMatch、toArray操作、min、max、findFirst、findAny、reduce、collect操作 示例说明
package com.zpy.demo.java8;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @Author: Administrator
* @Description:
* @Date:Create:in 2019/10/16 15:53
*/
public class LambdaDemo {
public static void main(String[] args){
List<Person> p1=getPersonList();
/**
* 遍历
void forEach(Consumer<? super T> action);
void forEachOrdered(Consumer<? super T> action)
*/
List<String> strsss = Arrays.asList("a", "b", "c");
strsss.stream().forEachOrdered(System.out::print);//abc
strsss.stream().forEach(System.out::print);//abc
strsss.parallelStream().forEachOrdered(System.out::print);//abc
strsss.parallelStream().forEach(System.out::print);//bca
//先看第一段输出和第二段输出,使用的是stream的流,这个是一个串行流,也就是程序是串行执行的,所有看到遍历的结果都是按照集合的元素放入的顺序;
//看第三段和第四段输出,使用的parallelStream的流,这个流表示一个并行流,也就是在程序内部迭代的时候,会帮你免费的并行处理
//第三段代码的forEachOrdered表示严格按照顺序取数据,forEach在并行中,随机排列了;这个也可以看出来,在并行的程序中,如果对处理之后的数据,没有顺序的要求,使用forEach的效率,肯定是要更好的
/**
* 按条件过滤
* Stream<T> filter(Predicate<? super T> predicate);
* 这个方法,传入一个Predicate的函数接口,这个接口传入一个泛型参数T,做完操作之后,返回一个boolean值;filter方法的作用,
* 是对这个boolean做判断,返回true判断之后的对象,下面一个案例,可以看到怎么使用
*/
//Predicate 接口定义 可以用作判断使用
Predicate<Person> predicate = x -> x.getAge() > 5;//判断年龄是否大于5
boolean boo=predicate.test(p1.get(1));
// 字符串的非空判断
Predicate<String> predicateStr = x -> null == x || "".equals(x);
System.out.println(predicateStr.test(""));//true
//过滤年龄大于5的person 返回list
List<Person> personList=p1.stream().filter(predicate).collect(Collectors.toList());
List<Person> personList2=p1.stream().filter(person -> person.getAge()>5).collect(Collectors.toList());
/**
* map 类型转换
* <R> Stream<R> map(Function<? super T, ? extends R> mapper);
* 这个方法传入一个Function的函数式接口,这个接口,接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象,
* 这个表示,调用这个函数后,可以改变返回的类型,先看下面的案例
*/
Function<Integer, String> function1 = x -> x +"www";//x为传入参数int类型 将它链接一个字符串 返回String类型
String zw=function1.apply(5);//结果 5www
//将p1中的年龄提取出来成一个list
List<Integer> ages=p1.stream().map(person -> person.getAge()).collect(Collectors.toList());
/**
* flatMap操作
* <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
* 这个接口,跟map一样,接收一个Fucntion的函数式接口,不同的是,Function接收的泛型参数,第二个参数是一个Stream流;方法,
* 返回的也是泛型R,具体的作用是把两个流,变成一个流返回,下面,我们看一个案例,来详细解答,怎么把两个流的内容,
* 变成一个流的内容
*/
String[] strss = { "aaa", "bbb","ccc" };
Arrays.stream(strss).map(str -> str.split("")).forEach(System.out::println);// java.lang.String;@53d8d10a
List<String > w2=Arrays.stream(strss).map(str -> str.split("")).flatMap(Arrays::stream).collect(Collectors.toList());// aaabbbccc
Arrays.stream(strss).map(str -> str.split("")).flatMap(str -> Arrays.stream(str)).forEach(System.out::println);// aaabbbccc
/**
* 去重复
Stream<T> distinct();
*/
//去重复后输出
p1.stream().distinct().forEach(System.out::println);
/**
* 排序
Stream<T> sorted();
根据属性排序
Stream<T> sorted(Comparator<? super T> comparator);
*/
//排序 按person 中的age属性排序
p1.stream().sorted((p0,p2)->p0.getAge()-p2.getAge()).forEach(System.out::println);
p1.stream().sorted(Comparator.comparing(person -> person.getAge())).forEach(System.out::println);
p1.stream().sorted(Comparator.comparing(Person::getAge)).forEach(System.out::println);
/**
* 对对象的属性进行操作
Stream<T> peek(Consumer<? super T> action);
*/
//对对像进行操作 把年龄大于2的人的名字加上 青年
//p1.stream().filter(person -> person.getAge()>2).peek(person -> person.setName("青年"+person.getName())).forEach(System.out::println);
/**
* 截断--取先maxSize个对象
Stream<T> limit(long maxSize);
截断--忽略前N个对象
Stream<T> skip(long n);
*/
//截断--取先maxSize个对象
p1.stream().limit(2).forEach(System.out::println);
//截断--忽略前N个对象
p1.stream().skip(2).forEach(System.out::println);
/**
long count();
count方法,跟List接口的size一样,返回的都是这个集合流的元素的长度,不同的是,流是集合的一个高级工厂,
中间操作是工厂里的每一道工序,我们对这个流操作完成后,可以进行元素的数量的和;
boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
剩下的三个方法,传入的都是Predicate的函数式接口
anyMatch表示,判断的条件里,任意一个元素成功,返回true
allMatch表示,判断条件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
*/
//统计有几个年龄==10的人
long cou=p1.stream().filter(person -> person.getAge()==10).count();
//判断list中是否有年龄==2的person
boolean si= p1.stream().anyMatch(person -> person.getAge()==2);//true
//判断list中是否有所有人年龄==2
boolean si2= p1.stream().allMatch(person -> person.getAge()==2);//false
//判断list中是否有所有人年龄==2
boolean si3= p1.stream().noneMatch(person -> person.getAge()==2);//false
/**
* 终端操作 toArray操作
* public final <A> A[] toArray(IntFunction<A[]> generator)
*/
List<String> st = Arrays.asList("a", "b", "c");
String[] dd = st.stream().toArray(str -> new String[st.size()]);
String[] dd1 = st.stream().toArray(String[]::new);
Object[] obj = st.stream().toArray();
String[] dd2 = st.toArray(new String[st.size()]);
Object[] obj1 = st.toArray();
//可以看到,前三个,是调用的stream的toArray的函数,以及一些用法,后面的两个,是直接调用的List接口的toArray函数,List接口里的
/**
* 终端操作 min,max,findFirst,findAny操作
Optional<T> min(Comparator<? super T> comparator); //集合中的最小值
Optional<T> max(Comparator<? super T> comparator); //集合中的最大值
Optional<T> findFirst(); //返回集合中的第一个
Optional<T> findAny(); //返回这个集合中,取到的任何一个对象
*/
//Optional的get方法,是取到操作后的对象,
List<Integer> integerList = Arrays.asList(1,5,8,3,9);
//Optional min=integerList.stream().min((o1,o2)-> o1.compareTo(o2));
Optional min=integerList.stream().min(Comparator.naturalOrder());
Optional max=integerList.stream().max((o1,o2)-> o1.compareTo(o2));
System.out.println("最小值"+min.get()+" 最大值-- "+max.get());
//查询list中年龄最小的person
Optional aaa= p1.stream().min(Comparator.comparing(person -> person.getAge()));
Person pmin=(Person)aaa.get();
List<String> stringss = Arrays.asList("d", "b", "a", "c", "a");
Optional<String> aa = stringss.stream().filter(str -> !str.equals("a")).findFirst();
Optional<String> bb = stringss.stream().filter(str -> !str.equals("a")).findAny();
Optional<String> aa1 = stringss.parallelStream().filter(str -> !str.equals("a")).findFirst();
Optional<String> bb1 = stringss.parallelStream().filter(str -> !str.equals("a")).findAny();
System.out.println(aa.get() + "===" + bb.get());// d===d
System.out.println(aa1.get() + "===" + bb1.get());// d===b or d===c
/**
*终端操作reduce操作
* reduce 是一种归约操作,将流归约成一个值的操作叫做归约操作,用函数式编程语言的术语来说,这种称为折叠(fold);
T reduce(T identity, BinaryOperator<T> accumulator);
这个函数,接受2个参数,第一个表示初始值,第二个值,传入的是一个函数式接口BinaryOperator,这个接口继承BiFunction;计算的表达式的规则;
Optional<T> reduce(BinaryOperator<T> accumulator);
这个接口。只用传入计算规则,初始值是list的第一个参数,返回的optional对象,预防list里,全部是null;
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
*/
Integer hc = integerList.stream().reduce(0, (a, b) -> a + b);//求和 identity 初始值
Optional<Integer> hc1 = integerList.stream().reduce((a, b) -> a + b);//求和
Optional<Integer> hc11 = integerList.stream().reduce((a, b) -> a * b);//求乘积
System.out.println(hc);
System.out.println(hc1.get());
/**
* 终端操作 collect操作
* <R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
第一个,是传入3个参数的抽象方法,
第二个只有一个参数的先看下stream中的collect操作Collectors静态工厂类,而在这个静态工厂类中,大部分的实现,
都是调用的三个参数的方法,几乎满足了我们日常中所有的操作;所以说,我们只看下,这个静态工厂类中,有哪些实现
*/
//转list
List<String> nameList = p1.stream().map(p -> p.getName()).collect(Collectors.toList());
//转set
Set<String> nameSet = p1.stream().map(p -> p.getName()).collect(Collectors.toSet());
// 转map,需要指定key和value,Function.identity()表示当前的Emp对象本身 原list中指定为key的字段不能有重复
Map<Integer,Person> personMap=p1.stream().collect(Collectors.toMap(p->p.getAge(),Function.identity()));
计算元素中的个数
Long count = p1.stream().collect(Collectors.counting());
// 数据求和 summingInt summingLong,summingDouble
Integer sumAges = p1.stream().collect(Collectors.summingInt(Person::getAge));//Person::getAge 等价于p->p.getAge()
// 平均值 averagingInt,averagingDouble,averagingLong
Double aveAges = p1.stream().collect(Collectors.averagingInt(Person::getAge));
// 综合处理的,求最大值,最小值,平均值,求和操作
// summarizingInt,summarizingLong,summarizingDouble
IntSummaryStatistics intSummary = p1.stream().collect(Collectors.summarizingInt(Person::getAge));
System.out.println(intSummary.getAverage());//
System.out.println(intSummary.getMax());//
System.out.println(intSummary.getMin());//
System.out.println(intSummary.getSum());//
/**
* IntSummaryStatistics
*/
IntSummaryStatistics stats=p1.stream().mapToInt(x->x.getAge()).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
// 连接字符串,当然也可以使用重载的方法,加上一些前缀,后缀和中间分隔符
String strEmp = p1.stream().map(emp -> emp.getName()).collect(Collectors.joining());
String strEmp1 = p1.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-"));
String strEmp2 = p1.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-", "前缀*", "&后缀"));
// maxBy 按照比较器中的比较结果刷选 最大值
Optional<Integer> maxAge = p1.stream().map(emp -> emp.getAge())
.collect(Collectors.maxBy(Comparator.comparing(Function.identity())));
// 最小值
Optional<Integer> minAge = p1.stream().map(emp -> emp.getAge())
.collect(Collectors.minBy(Comparator.comparing(Function.identity())));
System.out.println("max:" + maxAge);
System.out.println("min:" + minAge);
// 归约操作 求和
Optional ot=p1.stream().map(emp -> emp.getAge()).collect(Collectors.reducing((x, y) -> x+ y));
int rr=p1.stream().map(emp -> emp.getAge()).collect(Collectors.reducing(0, (x, y) -> x + y));
List<Person> dq=new ArrayList();
dq.add(new Person("广州",10));
dq.add(new Person("广州",10));
dq.add(new Person("北京",7));
dq.add(new Person("北京",5));
dq.add(new Person("武汉",6));
dq.add(new Person("杭州",8));
dq.add(new Person("上海",3));
// 分操作 groupingBy 根据姓名,把原list进行分组
Map<String, List<Person>> mapGroup = dq.stream().collect(Collectors.groupingBy(Person::getName));
// partitioningBy 分区操作 需要根据类型指定判断分区
Map<Boolean, List<Integer>> partitioningMap = p1.stream().map(emp -> emp.getAge())
.collect(Collectors.partitioningBy(age -> age > 5));
System.out.println("");
//根据对象的属性排序
//根据Dict对象的sort字段降序排序
dq.sort(Comparator.comparing(Person::getAge).reversed());
//根据Dict对象的sort字段升序排序
dq.sort(Comparator.comparing(Person::getAge));
}
private static List<Person> getPersonList(){
List<Person> p=new ArrayList<>();
Person rr=new Person("儿子2",10);
Person rr1=new Person("儿子2",10);
p.add(rr);
//p.add(rr1);
for (int i=0;i<8;i++){
Person person=new Person("儿子"+i,i);
p.add(person);
}
return p;
}
}