java8新特性 stream中间操作和终端操作示例说明java8新特性(查找、 排序、 过滤 、计算、 去重 、分组 等操作)

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;
    }

}

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值