转载

JDK8新特性

  • List

    • 这里的表示List中每一个元素,可以不指定类型,JDK会自动推测出类型,但是也是可以使用 () 加上类型
    • 如果有一条语句可以直接在后面输出,如果有多行,那么可以在后面使用 {} 指定
      Arrays.asList(1,2,4,1,76).forEach(e-> System.out.println(e));
         Arrays.asList(1,2,4,1,76).forEach((Integer e)-> System.out.println(e));
      
  • Set

    Set<Object> set=new HashSet<>(Arrays.asList(1,2,4,1,76));
       set.forEach(e-> System.out.println(e));
    
  • Map

    Map<Object,Object> map=new HashMap<>();
          map.put("2",2);
          map.put("4",5);
          //a,b两个元素分别是key和value
          map.forEach((a,b)->{
              System.out.println(a+"---"+b);
          });
    

lambda表达式轻松创建接口实例

  • 条件:该接口只能有一个需要实现的方法(默认方法除外)
    ()->{}
    item->{}
    (String item1,String item2)
    
  • FunctionalInterface :标记这个接口只能定义一个方法(除了默认的方法)
    @FunctionalInterface
    public interface UserService{
        Stringdisplay(String name);
    }
    
    @Test
       public void test1(){
           UserService userService=name -> {
               return name;
           };
           userService.display("che");
       }
    

接口的默认方法和静态方法

  • 默认方法不需要实现,但是可以被覆盖
    public interface Demo1{
    	
    	/**
    	 * 接口的静态方法
    	 */
    	static void display(){
    		System.out.println("cdc");
    	}
    	
    	/**
    	 * 默认方法可以不实现,但是可以被覆盖
    	 */
    	default void play(){
    		System.out.println("cdddd");
    	}
    }
    

Stream

  • Stream接口中包含许多对流操作的方法,这些方法分别为:
    • filter():对流的元素过滤
    • map():将流的元素映射成另一个类型
    • distinct():去除流中重复的元素
    • sorted():对流的元素排序
    • forEach():对流中的每个元素执行某个操作
    • peek():与forEach()方法效果类似,不同的是,该方法会返回一个新的流,而forEach()无返回
    • limit():截取流中前面几个元素
    • skip():跳过流中前面几个元素
    • toArray():将流转换为数组
    • reduce():对流中的元素归约操作,将每个元素合起来形成一个新的值
    • collect():对流的汇总操作,比如输出成List集合
    • anyMatch():匹配流中的元素,类似的操作还有allMatch()和noneMatch()方法
    • findFirst():查找第一个元素,类似的还有findAny()方法
    • max():求最大值
    • min():求最小值
    • count():求总数

filter

  • 过滤集合,实际是实现其中的test方法,返回的是一个Boolean类型的值,我们可以使用lambda表达式可以很轻松的实现集合的过滤
       @Test	
       public void test2(){
           User user1 = new User();
           user1.setName("chen");
           user1.setAge(22);
    
           User user3 = new User();
           user3.setName("zheng");
           user3.setAge(22);
    
           User user2 = new User();
           user2.setName("zhou");
           user2.setAge(30);
    
           List<User> users=new ArrayList<>();
           users.add(user1);
           users.add(user2);
           users.add(user3);
    /* 下面的语句类似如下
            *   users.stream().filter(item->item.getAge()>25).collect(Collectors.toList());
            */	
           List<User> collect = users.stream().filter(user -> {
               if (user.getAge() > 25) {
                   return true;
               } else {
                   return false;
               }
           }).collect(Collectors.toList());
       }
    

sorted

  • 有两个实现的方法,如下:

    Stream<T>sorted(Comparator<?super T> comparator);
    Stream<T>sorted();
    
  • 例子如下:

    Stream.of(1, 8, 5, 2, 1, 0, 9, 2, 0, 4, 8)
        .filter(n -> n > 2)     // 对元素过滤,保留大于2的元素
        .distinct()             // 去重,类似于SQL语句中的DISTINCT
        .skip(1)                // 跳过前面1个元素
        .limit(2)               // 返回开头2个元素,类似于SQL语句中的SELECT TOP
        .sorted()               // 对结果排序
        .forEach(System.out::println);
    
//按照age排序,实际上就是实现Comparator的接口方法compareTo
      users.sort((item1,item2)->{
          return item1.getAge()-item2.getAge();
      });

查找和匹配

  • Stream中提供的查找方法有anyMatch()、allMatch()、noneMatch()、findFirst()、findAny(),这些方法被用来查找或匹配某些元素是否符合给定的条件:
    // 检查流中的任意元素是否包含字符串"Java"
    boolean hasMatch = Stream.of("Java", "C#", "PHP", "C++", "Python")
            .anyMatch(s -> s.equals("Java"));
    
    // 检查流中的所有元素是否都包含字符串"#"
    boolean hasAllMatch = Stream.of("Java", "C#", "PHP", "C++", "Python")
            .allMatch(s -> s.contains("#"));
    
    // 检查流中的任意元素是否没有以"C"开头的字符串
    boolean hasNoneMatch = Stream.of("Java", "C#", "PHP", "C++", "Python")
            .noneMatch(s -> s.startsWith("C"));
    
    // 查找元素
    Optional<String> element = Stream.of("Java", "C#", "PHP", "C++", "Python")
            .filter(s -> s.contains("C"))
            // .findFirst() // 查找第一个元素
            .findAny();         // 查找任意元素
    

归约

map

  • map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

    List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    // 获取对应的平方数
    List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
    
  • map使用lambda表达式返回的类型就是最后的类型,下面我们将用户的年龄设置成两倍

    @Test
       public void test2(){
           User user1 = new User();
           user1.setName("chen");
           user1.setAge(22);
    
           User user3 = new User();
           user3.setName("zheng");
           user3.setAge(22);
    
           User user2 = new User();
           user2.setName("zhou");
           user2.setAge(40);
    
           List<User> users=new ArrayList<>();
           users.add(user1);
           users.add(user2);
           users.add(user3);
    
           List<User> list = users.stream().map(item -> {
               item.setAge(item.getAge() * 2);
               return item;
           }).collect(Collectors.toList());
       }
    

reduce

  • 将两个元素进行归约操作,比如两个元素相加,但是这个操作的返回值一定要和操作之前的类型相同
    //归约操作,返回的是一个Optional类型的
            Optional<Integer> optional = users.stream().map(item -> item.getAge()).reduce((item1, item2) -> item1 + item2);
            if (optional.isPresent()){
                System.out.println(optional.get());
            }
    

分组

  • 和关系数据库一样,流也提供了类似于数据库中GROUP BY分组的特性,由Collectors.groupingBy()方法提供:

    //根据age进行分组,返回的是Map集合,key就是分组后的age,value是user对象
            Map<Integer, List<User>> listMap = users.parallelStream().collect(Collectors.groupingBy(item -> item.getAge()));
            listMap.forEach((key,value)->{
                System.out.println(key+"--->"+value);
            });
    
  • 但实际情况可能比这复杂,比如将价格在0-50之间的书籍分成一组,50-100之间的分成一组,超过100的分成一组,这时候,我们可以直接使用Lambda表达式来表示这个分组逻辑:

    //根据age进行分组,返回的是Map集合,key就是分组后的age,value是user对象
            Map<String, List<User>> listMap = users.parallelStream().collect(Collectors.groupingBy(item -> {
                if (item.getAge() > 20) {
                    return "A";
                } else {
                    return "B";
                }
            }));
    
            listMap.forEach((key,value)->{
                System.out.println(key+"--->"+value);
            });
    

Optional

  • 文档
  • https://zhuanlan.zhihu.com/p/40966718

  • 创建方法:

    public static <T> Optional<T> of(T value)
    public static <T> Optional<T> ofNullable(T value)
    
  • 常用方法

    • public Optional<T> filter(Predicate<? super T> predicate) :过滤其中的元素,如果返回true,那么保留,返回false去除该元素
    • public T orElse(T other) :如果该元素的值为null,那么指定该值为other

      User user = new User(22, "chenjiabing");
      User user2 = Optional.ofNullable(user).filter(item->{
      	return item.getAge()>30;
      }).orElse(null);
      
    • public T orElseGet(Supplier<? extends T> other) :如果该值为空,那么就调用other的get方法,其中返回一个同种类型的对象

      Optional.ofNullable(user).filter(item->{
      	return item.getAge()>30;
      }).orElseGet(()->{
      	System.out.println("该值为空");
      	return new User(44, "zhengjiahe");
      });
      
    • public boolean isPresent() :判断当前的元素是否为null,如果为null返回false,否则返回true

    • public void ifPresent(Consumer<? super T> consumer) :如果不为空调用其中的方法
    • public <U> Optional<U> map(Function<? super T,? extends U> mapper) :如果为空直接返回一个空的Optional,不会调用map中的apply方法,如果不为空,那么调用apply方法
      Optional<Integer> map = Optional.ofNullable(null).map(item->{
      	System.out.println(item);
      	//返回值也决定着你的类型
      	return Integer.MAX_VALUE;
      });
      

Collectors

  • 针对集合操作的封装类,结合Stream编程客可以很简单的实现

toMap

  • List直接转换为Map,使用JDK1.8的Stream编程
  • Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper) :简单的将集合转换成Map,出现key重复的将直接抛出异常

    • keyMapper :指定的
    • valueMapper :指定的value
              Map<Integer, String> map = users.stream().collect(Collectors.toMap(User::getAge, User::getName));
      `
      
  • public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction) :用于解决key冲突的情况

    • mergeFunction :用于当出现key冲突的情况下解决方法,其中只需要实现apply方法即可,两个参数分别是重复的map的value值,返回值是指定的值
      Map<Integer, String> map = users.stream().collect(Collectors.toMap(User::getAge, User::getName,(v1,v2)->v1+","+v2));
      

toList

  • 将结果转换成一个List集合
    List<Integer> list = Stream.of(1, 2, 3, 4).collect(Collectors.toList());
    

toSet

  • 将结果转换成一个Set集合
    Set<Integer> set = Stream.of(1, 2, 3, 4).collect(Collectors.toSet());
    

groupingBy

  • 将所得的结果根据指定的内容进行分组,所得结果是一个Map类型的数据
  • public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)

    • 指定的key,value的默认类型为List
      Map<Integer, List<Integer>> map = Stream.of(1, 1, 3, 10, 2, 3, 4).collect(
                 Collectors.groupingBy(Integer::intValue));
      
  • `public static Collector

    Collector<? super T, A, D> downstream)`
    • 第一个参数是指定的key,第二个参数是指定的value的类型
      Map<Integer, Set<Integer>> map = Stream.of(1, 1, 3, 10, 2, 3, 4).collect(
                 Collectors.groupingBy(Integer::intValue, Collectors.toSet()));
      
原文  https://chenjiabing666.github.io/2019/06/12/JDK8新特性/
正文到此结束
Loading...