java8新特性

Lambda表达式

java8 内置的四大核心函数式接口
在这里插入图片描述

  • Consumer : 消费型接口

  •      void accept(T t)
    
  • Supplier : 供给型接口

  •      T get();
    
  • Function<T,R> : 函数型接口

  •  R apply(T t);
    
  • Predicate :断言型接口

  •  boolean test(T t);
    
//    Predicate<T>断言型接口
    @Test
    public void test4(){
        List<String> list = Arrays.asList("aaa","bbb","ccc");
        List<String> manzu = filterStr(list, (x) -> x.length()>2);
        System.out.println(manzu);
    }
//    需求:将满足条件的字符串放入集合中
    public List<String> filterStr(List<String> list, Predicate<String> str){
        List<String> strList = new ArrayList<>();
        for(String strs : list){
            if (str.test(strs)){
                strList.add(strs);
            }
        }
        return strList;
    }

//      Function<T,R> 函数型接口
    @Test
    public void test3(){
        String s = strHandler("\t\t\t\t    aaa", (str) -> str.trim());
        System.out.println(s);
    }
//    需求:用于处理字符串
    public String strHandler(String str, Function<String,String> fun){
        return fun.apply(str);
    }


//    Supplier<T> 供给型接口:
    @Test
    public void test2(){
        List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
        System.out.println(numList);
    }

    public List<Integer> getNumList(int num , Supplier<Integer> supplier){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            Integer n = supplier.get();
            list.add(n);
        }
        return list;
    }

//    Consumer<T> 消费型接口:
    @Test
    public void test1(){
        happy(10000,con-> System.out.println(con));
    }

    public void happy(double money, Consumer<Double> con){
        con.accept(money);
    }
  • 一.方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用"方法应用"
  •  (可以理解为方法引用是Lambda表达式的另外一种方式)
    
  • 主要语法格式有三种
    
  • 对象::实例方法名
  • 类::静态方法名
  • 类::实例方法名
  • 注意
    Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致
  • 若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用Classname::method
  • 二.构造器引用
  • 格式
    ClassName::new
    注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致
  • 三.数组引用
  • Type::new;
//    数组引用
    @Test
    public void test7(){
        Function<Integer,String[]> fun = (x) -> new String[x];
        String [] strs = fun.apply(1);
        System.out.println(strs.length);

        Function<Integer,String[]> fun2 = String[]::new;
        String[] apply = fun2.apply(20);
        System.out.println(apply.length);


    }

    @Test
    public void test5(){
        Supplier<Employee> sup = () -> new Employee();
//        构造器引用方式
        Supplier<Employee> sup2 = Employee::new;
        Employee employee = sup2.get();
        System.out.println(employee);
    }

//  构造器引用
    @Test
    public void test6(){
//        Function<Integer,Employee> fun = (x) -> new Employee(x);
        Function<Integer,Employee> fun2 = Employee::new;
        Employee employee = fun2.apply(11);
        System.out.println(employee);
    }

//  类::实例方法名
    @Test
    public void test4(){
        BiPredicate<String,String> bp = (x,y) -> x.equals(y);

        BiPredicate<String,String> bp2 = String::equals;
    }

//  类::静态方法名
    @Test
    public void test3 (){
        Comparator<Integer> com = (x,y) -> Integer.compare(x,y);

        Comparator<Integer> com2 = Integer::compare;

        com2.compare(1,2);
    }
//    对象::实例方法名
    @Test
    public void test1(){
        Consumer<String> con = (x) -> System.out.println(x);

        PrintStream printStream = System.out;
        Consumer<String> con1 = printStream::println;

        Consumer<String> con2 = System.out::println;
        con2.accept("aaa");
    }

    @Test
    public void test2(){
        Employee employee = new Employee("张三",1,1);
        Supplier<String> sup = () -> employee.getName();
        String s = sup.get();
        System.out.println(s);


        Supplier<String> sup1 = employee::getName;
        String s1 = sup1.get();
        System.out.println(s1);
    }

Stream

1.创建stream

//  创建stream
    @Test
    public void test1(){
//        1.可以通过Collection系列集合提供的stream()或parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

//        2.通过Arrays中的静态方法stream()获取数组流
        Employee[] emps = new Employee[10];
        Stream<Employee> stream2 = Arrays.stream(emps);

//        3.通过Stream类中的静态方法of()
        Stream<String> stream3 = Stream.of("aa", "bb", "cc");

//        4.创建无线流
//        迭代
        Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
        stream4.limit(10).forEach(System.out::println);
//        生成
        Stream.generate(() -> Math.random()).limit(5).forEach(System.out::println);
    }

2.中间操作

1.filter,distinct,limit,skip

在这里插入图片描述

    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,99.999),
            new Employee("李四",38,9999.9999),
            new Employee("王五",50,99.999),
            new Employee("赵六",55,99.999),
            new Employee("田七",18,99.999),
            new Employee("田七",18,99.999),
            new Employee("田七",18,99.999)
    );
    /*
    *  筛选与切片
    * filter ---接收Lambda
    * limit ---截断流
    * skip ---跳过
    * distinct----筛选,通过hashcode() 和 equals去重
    * */
//    内部迭代:迭代操作有Stream API完成
    @Test
    public void test1(){
//        中间操作,不会执行任何操作
        Stream<Employee> stream_api = employees.stream().filter((e) -> {
            System.out.println("Stream API 的中间操作");
            return e.getAge() > 18;
        });

//        终止操作:一次性执行全部内容,即"惰性求值"
        stream_api.forEach(System.out::println);
    }
//    外部迭代:
    @Test
    public void test2(){
        Iterator<Employee> iterator = employees.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

    @Test
    public void test3(){
        employees.stream().filter((e)->e.getSalary()>99).limit(2).forEach(System.out::println);
    }

    @Test
    public void test4(){
        employees.stream().filter((e)->e.getSalary()>99).distinct().forEach(System.out::println);
    }

2.map,flatMap

   /*
    * 映射
    * map ---接收Lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
    * flatMap --- 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连城一个流
    *
    * */
    @Test
    public void test5(){
            List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
            list.stream().map((e)-> {return e.toUpperCase();}).forEach(System.out::println);

        System.out.println("--------------------");

        employees.stream().map(Employee::getName).forEach(System.out::println);

        System.out.println("--------------------");
        Stream<Stream<Character>> streamStream = list.stream().map(TestStreamAPI2::filterCharacter);
        streamStream.forEach((e) -> e.forEach(System.out::println));

        System.out.println("--------------------");
        Stream<Character> characterStream = list.stream().flatMap(TestStreamAPI2::filterCharacter);
        characterStream.forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter (String str){
        List<Character> list = new ArrayList<>();
        for (Character ch:str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }

3.sorted排序

    /*
    * 排序
    * sorted() ---自然排序
    * sorted(Comparator com) ---定制排序
    * */
    @Test
    public void test7(){
        List<String> list = Arrays.asList("ccc","bbb","aaa","ddd");
        list.stream().sorted().forEach(System.out::println);
        System.out.println("-------------------------");
        employees.stream().sorted((e1,e2)->{
            if (e1.getAge().equals(e2.getAge())){
                return e1.getName().compareTo(e2.getName());
            }else {
                return e1.getAge().compareTo(e2.getAge());
            }
        }).forEach(System.out::println);
    }

终止操作

1.allMatch,anyMatch,noneMatch,FindFirst,findAny,count,max,min

    /*
    * allMatch ---检查是否匹配所有元素
    * anyMatch ---检查是否至少匹配一个元素
    * noneMatch ---检查是否没有匹配所有元素
    * FindFirst ----返回第一个元素
    * findAny ---返回当前流中任意元素
    * count ---返回流中元素个数
    * max ---返回流中最大值
    * min ---返回流中最小值
    *
    * */
@Test
public void test(){
    boolean b = employees.stream().allMatch((e)->e.getStatus().equals(Employee.Status.FREE));
    System.out.println(b);

    boolean b1 = employees.stream().anyMatch((e) -> e.getStatus().equals(Employee.Status.FREE));
    System.out.println(b1);

    boolean b2 = employees.stream().noneMatch((e) -> e.getStatus().equals(Employee.Status.FREE));
    System.out.println(b2);

    Optional<Employee> op = employees.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();

    System.out.println(op.get());

    Optional<Employee> any = employees.stream().filter((e) -> e.getStatus().equals(Employee.Status.FREE)).findAny();

    System.out.println(any.get());
}
    @Test
public void test2(){
    long count = employees.stream().count();
    System.out.println(count);

    Optional<Employee> max = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
    System.out.println(max.get());

    Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compare);
    System.out.println(min.get());
}

2.reduce

    /*
    * 归约
      reduce(T identity,BinaryOperator) 可以将流中元素反复结合起来,得到一个值
     */
    @Test
    public void test3(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream().reduce(0, (x, y) -> x + y);
        System.out.println(sum);

        System.out.println("-----------------------------------");
        Optional<Double> op = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(op.get());
    }

3.collect

    /*
    * 收集
    * Collect ---将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素
    * */
    @Test
    public void test4(){
        List<String> collect = employees.stream().map(Employee::getName).collect(Collectors.toList());
        collect.forEach(System.out::println);
        System.out.println("--------------------------");
        Set<String> set = employees.stream().map(Employee::getName).collect(Collectors.toSet());
        set.forEach(System.out::println);
        System.out.println("---------------------");
        HashSet<String> hs = employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
        hs.forEach(System.out::println);
    }

4.总数,平均值,总和,最大值,最小值

    @Test
    public void test5(){
//        总数
        Long collect = employees.stream().collect(Collectors.counting());
        System.out.println(collect);
//        平均值
        Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(avg);
//        总和
        Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getAge));
        System.out.println(sum);
//        最大值
        Optional<Employee> opt = employees.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(opt.get());
//        最小值
        Optional<Double> opt1 = employees.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
        System.out.println(opt1.get());
    }

5.分组

    @Test
    public void test6(){
        Map<Employee.Status, List<Employee>> collect = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(collect);
    }

6.多级分组

//多级分组
    @Test
    public void test7(){
        Map<Employee.Status, Map<String, List<Employee>>> collect = employees.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                    if (e.getAge() <= 35) {
                        return "青年";
                    } else if (e.getAge() <= 50) {
                        return "中年";
                    } else {
                        return "老年";
                    }
                }
        )));
        System.out.println(collect);
    }

7.分区

//    分区
    @Test
    public void test8(){
        Map<Boolean, List<Employee>> map = employees.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
        System.out.println(map);
    }

收集

//      收集
//    collect---将流转换为其他形式,接收一个collector接口的实现,用于给Stream中元素做汇总的方法
    @Test
    public void test9(){
        DoubleSummaryStatistics collect = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(collect.getSum());
        System.out.println(collect.getAverage());
        System.out.println(collect.getMax());
    }
    @Test
    public void test10(){
        employees.stream().map(Employee::getName).collect(Collectors.joining(","));
    }

并行流和串行流

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//    java8并行流
    @Test
    public void test(){
        Instant start = Instant.now();
        LongStream.rangeClosed(0,1000000000000L).parallel().reduce(0,Long::sum);
        Instant end = Instant.now();
        System.out.println("消耗时间为:"+ Duration.between(start,end).toMillis());
    }

Option容器类

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值