zoukankan      html  css  js  c++  java
  • jdk1.8特性

    一、lambda表达式

    lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码。

    先来体验一下lambda最直观的优点:简洁代码

      //匿名内部类
      Comparator<Integer> cpt = new Comparator<Integer>() {
          @Override
          public int compare(Integer o1, Integer o2) {
              return Integer.compare(o1,o2);
          }
      };
    
      TreeSet<Integer> set = new TreeSet<>(cpt);
    
      System.out.println("=========================");
    
      //使用lambda表达式
      Comparator<Integer> cpt2 = (x,y) -> Integer.compare(x,y);
      TreeSet<Integer> set2 = new TreeSet<>(cpt2);

    只需要一行代码,极大减少代码量!!

    这样一个场景,在商城浏览商品信息时,经常会有条件的进行筛选浏览,例如要选颜色为红色的、价格小于8000千的….

    // 筛选颜色为红色
    public  List<Product> filterProductByColor(List<Product> list){
        List<Product> prods = new ArrayList<>();
        for (Product product : list){
            if ("红色".equals(product.getColor())){
                prods.add(product);
            }
        }
        return prods;
     }
    
    // 筛选价格小于8千的
    public  List<Product> filterProductByPrice(List<Product> list){
        List<Product> prods = new ArrayList<>();
        for (Product product : list){
            if (product.getPrice() < 8000){
                prods.add(product);
            }
        }
        return prods;
     }

    我们发现实际上这些过滤方法的核心就只有if语句中的条件判断,其他均为模版代码,每次变更一下需求,都需要新增一个方法,然后复制黏贴,假设这个过滤方法有几百行,那么这样的做法难免笨拙了一点。如何进行优化呢?

    优化一:使用lambda表达式

    定义一个MyPredicate接口

    public interface MyPredicate <T> {
        boolean test(T t);
    }

    定义过滤方法:

    public List<Product> filterProductByPredicate(List<Product> list,MyPredicate<Product> mp){
            List<Product> prods = new ArrayList<>();
            for (Product prod : list){
                if (mp.test(prod)){
                    prods.add(prod);
                }
            }
            return prods;
        }

    使用lambda表达式进行过滤:

    @Test
    public void test4(){
          List<Product> products = filterProductByPredicate(proList, (p) -> p.getPrice() < 8000);
          for (Product pro : products){
              System.out.println(pro);
          }
      }

    在jdk1.8中还有更加简便的操作 Stream API

    优化二:使用Stream API

    甚至不用定义过滤方法,直接在集合上进行操作

    // 使用jdk1.8中的Stream API进行集合的操作
    @Test
    public void test(){
        // 根据价格过滤
        proList.stream()
               .fliter((p) -> p.getPrice() <8000)
               .limit(2)
               .forEach(System.out::println);
    
        // 根据颜色过滤
        proList.stream()
               .fliter((p) -> "红色".equals(p.getColor()))
               .forEach(System.out::println);
    
        // 遍历输出商品名称
        proList.stream()
               .map(Product::getName)
               .forEach(System.out::println);
    }

    Lmabda表达式的语法总结: () -> ();

    前置语法
    无参数无返回值 () -> System.out.println(“Hello WOrld”)
    有一个参数无返回值 (x) -> System.out.println(x)
    有且只有一个参数无返回值 x -> System.out.println(x)
    有多个参数,有返回值,有多条lambda体语句 (x,y) -> {System.out.println(“xxx”);return xxxx;};
    有多个参数,有返回值,只有一条lambda体语句 (x,y) -> xxxx

    口诀:左右遇一省括号,左侧推断类型省

    注:当一个接口中存在多个抽象方法时,如果使用lambda表达式,并不能智能匹配对应的抽象方法,因此引入了函数式接口的概念。

    二、函数式接口

    函数式接口的提出是为了给Lambda表达式的使用提供更好的支持。 

    函数式接口: 简单来说就是只定义了一个抽象方法的接口,并且还提供了注解:@FunctionalInterface。

    常见的四大函数式接口

    Consumer 《T》:消费型接口,有参无返回值

        @Test
        public void test(){
            changeStr("hello",(str) -> System.out.println(str));
        }
    
        /**
         *  Consumer<T> 消费型接口
         * @param str
         * @param con
         */
        public void changeStr(String str, Consumer<String> con){
            con.accept(str);
        }

    Supplier 《T》:供给型接口,无参有返回值

        @Test
        public void test2(){
            String value = getValue(() -> "hello");
            System.out.println(value);
        }
    
        /**
         *  Supplier<T> 供给型接口
         * @param sup
         * @return
         */
        public String getValue(Supplier<String> sup){
            return sup.get();
        }

    Function 《T,R》::函数式接口,有参有返回值

        @Test
        public void test3(){
            Long result = changeNum(100L, (x) -> x + 200L);
            System.out.println(result);
        }
    
        /**
         *  Function<T,R> 函数式接口
         * @param num
         * @param fun
         * @return
         */
        public Long changeNum(Long num, Function<Long, Long> fun){
            return fun.apply(num);
        }

    Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型

    public void test4(){
            boolean result = changeBoolean("hello", (str) -> str.length() > 5);
            System.out.println(result);
        }
    
        /**
         *  Predicate<T> 断言型接口
         * @param str
         * @param pre
         * @return
         */
        public boolean changeBoolean(String str, Predicate<String> pre){
            return pre.test(str);
        }

     总结:函数式接口的提出是为了让我们更加方便的使用lambda表达式,不需要自己再手动创建一个函数式接口,直接拿来用就好了。

    三、方法引用和构造器引用

    四、Stream API

    五、接口中默认的方法与静态方法

    六、新时间日期API

    七、其他特性

  • 相关阅读:
    软件测试
    python集合
    python基础(一)
    python布尔(空值)
    2013-12-15
    卸载IE9,IE10,IE11
    <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
    Log4j.properties配置详解
    WinCVS提交时出现错误 cvs server: C:/WINDOWS/TEMP/cvs**.tmp: No such file or directory 的解决方案
    Available Memory Is Low
  • 原文地址:https://www.cnblogs.com/chong-zuo3322/p/13640426.html
Copyright © 2011-2022 走看看