• Java8简明学习之Lambda表达式


    函数式接口

      就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,函数式接口可以被隐式转换为lambda表达式。

      之前已有的函数式接口:
      java.lang.Runnable
      java.util.concurrent.Callable
      java.util.Comparator
      java.io.FileFilter

      1.8新增的函数式接口:
      java.util.function包下

      Predicate<T>——接收 T 并返回 boolean (常用)
      Consumer<T>——接收 T,不返回值 (常用)
      Function<T, R>——接收 T,返回 R (常用)
      Supplier<T>——提供 T 对象(例如工厂),不接收值
      UnaryOperator<T>——接收 T 对象,返回 T
      BinaryOperator<T>——接收两个 T,返回 T

    lambda表达式

      lambda表达式的语法由参数列表、箭头符号 -> 和函数体组成。函数体既可以是一个表达式,也可以是一个语句块。
      eg: (int x, int y) -> x + y (表达式)
      eg:(Integer e) -> {
        double sqrt = Math.sqrt(e);
        double log = Math.log(e);

        return sqrt + log;
      } (语句块)
      意义:传入参数x和y,返回x和y的和
      表达式:表达式会被执行然后返回执行结果。
      语句块:语句块中的语句会被依次执行,就像方法中的语句一样。

    方法引用:

      方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。
      方法引用有很多种,它们的语法如下:
      静态方法引用:ClassName::methodName
      实例上的实例方法引用:instanceReference::methodName
      超类上的实例方法引用:super::methodName
      类型上的实例方法引用:ClassName::methodName
      构造方法引用:Class::new
      数组构造方法引用:TypeName[]::new

       eg:

    List<String> names5 = Arrays.asList("peter", "anna", "mike", "xenia");
            names5.sort(String::compareTo);
            System.out.println(names5);
    
    

    public void testFun1() {
    // comparing 是 Function<? super T, ? extends U> Function<T, R>——接收 T,返回 R
    Person p1 = new Person();
    p1.setName("hy");
    p1.setAge(18);

    
    

    Person p2 = new Person();
    p2.setName("dax");
    p2.setAge(19);

    
    

    Person[] people = {p1, p2};
    Comparator<Person> byName = Comparator.comparing(Person::getName);
    Arrays.sort(people, byName);
    for (Person person : people) {
    System.out.println(person);
    }
    }

    
    

     Stream

    Stream与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念,Stream 是对集合(Collection)对象功能的增强。

    eg:内部迭代和外部迭代

     void innerOrOuter() {
            List<Person> list = new ArrayList<>();
            Person p1 = new Person();
            p1.setName("hy");
            p1.setAge(18);
    
            Person p2 = new Person();
            p2.setName("dax");
            p2.setAge(19);
    
            list.add(p1);
            list.add(p2);
    
            for (Person p: list) {
                p.setAge(20);
            }
            System.out.println(list);
    
            List<Person> list2 = new ArrayList<>();
            Person p21 = new Person();
            p21.setName("hy");
            p21.setAge(18);
    
            Person p22 = new Person();
            p22.setName("dax");
            p22.setAge(19);
    
            list2.add(p21);
            list2.add(p22);
    
            list2.stream().forEach(p->p.setAge(20));
            System.out.println(list2);
        }

      Stream通用语法:

      Stream的操作:
      Intermediate(中间操作):
        map (mapToInt, flatMap 等)、 filter、 distinct(去重)、 sorted(排序)、 peek(对某个元素做单独处理生成新的Stream)、
        limit(取前N个元素)、 skip(丢弃前N个元素)、 parallel、 sequential、 unordered

      Terminal(结束操作,非短路操作):
        forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

      Short-circuiting(结束操作,短路操作):
        anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

      代表例子:

    @Test
    public void testNormal() {
        // 1 线程
        new Thread(()-> testThread()).start();
    
        // 2 遍历集合
        List<String> list = Arrays.asList("abd", "nba", "cba", "mctrady");
        list.stream().forEach(n-> System.out.println(n));
        list.forEach(n-> System.out.println(n));
    
        // 3 map运用
        List<Integer> listInt = Arrays.asList(123, 456, 789, 101);
        listInt.stream().map(n->n*10).forEach(n-> System.out.println(n));
        System.out.println(listInt.stream().mapToInt(n->n).sum());
        System.out.println(listInt.stream().mapToInt(n->n).average().getAsDouble());
    
        // 4 filter
        List<Integer> listInt2 = Arrays.asList(123, 456, 789, 101);
        listInt2.stream().filter(n->n>200).forEach(n-> System.out.println(n));
    
    
        // 5 对每个元素应用函数
        List<Integer> listInt3 = Arrays.asList(123, 456, 789, 101);
        String str = listInt3.stream().map(n->n.toString()).collect(Collectors.joining(","));
        System.out.println(str);
    }
    
    private void testThread() {
        System.out.println("线程操作");
    }
    List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
            Collections.sort(names, new Comparator<String>() {
                @Override
                public int compare(String a, String b) {
                    return b.compareTo(a);
                }
            });
            System.out.println(names);
    
            List<String> names1 = Arrays.asList("peter", "anna", "mike", "xenia");
            Collections.sort(names1, (String a, String b) -> {
                return b.compareTo(a);
            });
            System.out.println(names1);
    
            List<String> names2 = Arrays.asList("peter", "anna", "mike", "xenia");
            Collections.sort(names2, (String a, String b) -> b.compareTo(a));
            System.out.println(names2);
    
            List<String> names3 = Arrays.asList("peter", "anna", "mike", "xenia");
            Collections.sort(names3, (a, b) -> b.compareTo(a));
            System.out.println(names3);
    
            List<String> names4 = Arrays.asList("peter", "anna", "mike", "xenia");
            Collections.sort(names4, String::compareTo);
            System.out.println(names4);
    
            List<String> names5 = Arrays.asList("peter", "anna", "mike", "xenia");
            names5.sort(String::compareTo);
            System.out.println(names5);
    
            List<String> names6 = Arrays.asList("peter", "anna", "mike", "xenia");
            // 反转
            names6.sort(Comparator.comparing(String::toString).reversed());
            System.out.println(names6);

      

    public void testStream() throws ClassNotFoundException {
            List<Person> list = new ArrayList<>();
            Person p1 = new Person();
            p1.setName("hy");
            p1.setAge(18);
    
            Person p2 = new Person();
            p2.setName("dax");
            p2.setAge(19);
    
            list.add(p1);
            list.add(p2);
    
            System.out.println(list);
    
            list.stream().forEach(p -> p.setAge(20));
    
            System.out.println(list);
    
            list.stream().filter(s->s.getName().equals("hy")).forEach(p->p.setAge(21));
            System.out.println(list);
    
            List<Person> listHy = list.stream().filter(s->s.getName().equals("hy") && s.getAge() == 21).collect(Collectors.toList());
            System.out.println(listHy);
    
            int age = list.stream().mapToInt(s->s.getAge()).sum();
            System.out.println("年龄总和:" + age);
    
            Optional<Person> firstHy = list.stream()
                    .filter(s -> s.getName().equals("hy"))
                    .findFirst();
            Person person = firstHy.get();
            System.out.println(person);
        }

      总结:

      关于lambda和Stream的学习暂时先到这,如果日常用的就是1.8版本,这些就慢慢熟悉了,习惯了1.7以前面向对象编程的思维需要一些时间转换。而1.8里面lambda和Stream无疑是让Java更加的拥抱变化,在函数式编程里面也有了一些说话的位置。

      参考:

      http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features/

      https://blog.csdn.net/hanyingzhong/article/details/60965197

      https://segmentfault.com/a/1190000008876546

  • 相关阅读:
    存储过程3前台
    最简单Login程序
    存储过程前台2
    程序员 开发工具箱
    存储过程4前台
    存储过程 insert
    公司网络解决方案
    存储过程前台
    linux常用指令
    ReentrantLock源码解析3优先响应中断的lockInterruptibly
  • 原文地址:https://www.cnblogs.com/daily-note/p/9361185.html
Copyright © 2020-2023  润新知