• Java8必知必会


    Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及 java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。

    Lambda表达式的语法
    基本语法:

    (parameters) -> expression
    或:

    (parameters) ->{ statements; }
    基本lambda例子:集合的forEach(()->{})

    // 使用 lambda 表达式以及函数操作(functional operation)  
    players.forEach((player) -> System.out.print(player + "; "));  
       
    // 在 Java 8 中使用双冒号操作符(double colon operator)  
    players.forEach(System.out::println); 
    使用lambdas 来实现 Runnable接口 的示例:
    // 1.1使用匿名内部类
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello world !");
        }
    }).start();
    
    // 1.2使用 lambda expression
    new Thread(() -> System.out.println("Hello world !")).start();
    
    // 2.1使用匿名内部类
    Runnable race1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello world !");
        }
    };
    
    // 2.2使用 lambda expression
    Runnable race2 = () -> System.out.println("Hello world !");
    
    // 直接调用 run 方法(没开新线程哦!)
    race1.run();
    race2.run();
    使用Lambdas和Streams
    Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。
    System.out.println("给程序员加薪 5% :");
    Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
    javaProgrammers.forEach(giveRaise);
    phpProgrammers.forEach(giveRaise);
    Consumer:接口,Consumer<T>:Represents an operation that accepts a single input argument and returns no result.

    使用过滤器:

    System.out.println("下面是月薪超过 $1,400 的PHP程序员:")
    phpProgrammers.stream()
              .filter((p) -> (p.getSalary() > 1400))
              .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
    支持多重过滤:
    filter
    (Predicate<? super T> predicate)
    return:Stream<T>
    作用:Returns a stream consisting of the elements of this stream that match the given predicate.
    // 定义 filters
    Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);
    Predicate<Person> salaryFilter = (p) -> (p.getSalary() > 1400);
    Predicate<Person> genderFilter = (p) -> ("female".equals(p.getGender()));
    
    System.out.println("下面是年龄大于 24岁且月薪在$1,400以上的女PHP程序员:");
    phpProgrammers.stream()
              .filter(ageFilter)
              .filter(salaryFilter)
              .filter(genderFilter)
              .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
    // 重用filters
    System.out.println("年龄大于 24岁的女性 Java programmers:");
    javaProgrammers.stream()
              .filter(ageFilter)
              .filter(genderFilter)
              .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
    limit(long maxSize)
    return:Stream<T>
    作用:Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.

    System.out.println("最前面的3个 Java programmers:");
    javaProgrammers.stream()
              .limit(3)
              .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
    
    System.out.println("最前面的3个女性 Java programmers:");
    javaProgrammers.stream()
              .filter(genderFilter)
              .limit(3)
              .forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
    collect:是一个终端操作,它接收的参数是将流中的元素累积到汇总结果的各种方式(称为收集器)
    System.out.println("根据 name 排序,并显示前5个 Java programmers:");
    List<Person> sortedJavaProgrammers = javaProgrammers
              .stream()
              .sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
              .limit(5)
              .collect(toList()); //获取前5个保存到List中
    sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
    System.out.println("根据 salary 排序 Java programmers:");
    sortedJavaProgrammers = javaProgrammers
              .stream()
              .sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) )
              .collect( toList() );
    sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
    min和max方法

    System.out.println("工资最低的 Java programmer:");
    Person pers = javaProgrammers
              .stream()
              .min((p1, p2) -> (p1.getSalary() - p2.getSalary()))  //返回值:Optional<T>
              .get(); //A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value. 
    System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary());
    
    System.out.println("工资最高的 Java programmer:");
    Person person = javaProgrammers
              .stream()
              .max((p, p2) -> (p.getSalary() - p2.getSalary()))
              .get();
    System.out.printf("Name: %s %s; Salary: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary());
    结合 map 方法,我们可以使用 collect 方法来将我们的结果集放到一个字符串,一个 Set 或一个TreeSet中:

    System.out.println("将 PHP programmers 的 first name 拼接成字符串:");
    String phpDevelopers = phpProgrammers
              .stream()
              .map(Person::getFirstName)
              .collect(joining(" ; ")); // 在进一步的操作中可以作为标记(token)   
    
    System.out.println("将 Java programmers 的 first name 存放到 Set:");
    Set<String> javaDevFirstName = javaProgrammers
              .stream()
              .map(Person::getFirstName)
              .collect(toSet());
    
    System.out.println("将 Java programmers 的 first name 存放到 TreeSet:");
    TreeSet<String> javaDevLastName = javaProgrammers
              .stream()
              .map(Person::getLastName)
              .collect(toCollection(TreeSet::new));
    Streams 还可以是并行的(parallel)。

    System.out.println("计算付给 Java programmers 的所有money:");
    int totalSalary = javaProgrammers
              .parallelStream()
              .mapToInt(p -> p.getSalary())
              .sum();
    我们可以使用summaryStatistics方法获得stream 中元素的各种汇总数据。 接下来,我们可以访问这些方法,比如getMax, getMin, getSum或getAverage:
    //计算 count, min, max, sum, and average for numbers
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    IntSummaryStatistics stats = numbers
              .stream()
              .mapToInt((x) -> x)
              .summaryStatistics();
    System.out.println("List中最大的数字 : " + stats.getMax());
    System.out.println("List中最小的数字 : " + stats.getMin());
    System.out.println("所有数字的总和   : " + stats.getSum());
    System.out.println("所有数字的平均值 : " + stats.getAverage()); 


    附:.collect()参数

    工厂方法

    返回类型

    用于

    toList

    List<T>

    把流中所有元素收集到List中

    示例:List<Menu> menus=Menu.getMenus.stream().collect(Collector.toList())

    toSet

    Set<T>

    把流中所有元素收集到Set中,删除重复项

    示例:Set<Menu> menus=Menu.getMenus.stream().collect(Collector.toSet())

    toCollection

    Collection<T>

    把流中所有元素收集到给定的供应源创建的集合中

    示例:ArrayList<Menu> menus=Menu.getMenus.stream().collect(Collector.toCollection(ArrayList::new))

    Counting

    Long

    计算流中元素个数

    示例:Long count=Menu.getMenus.stream().collect(counting);

    SummingInt

    Integer

    对流中元素的一个整数属性求和

    示例:Integer count=Menu.getMenus.stream().collect(summingInt(Menu::getCalories))

    averagingInt

    Double

    计算流中元素integer属性的平均值

    示例:Double averaging=Menu.getMenus.stream().collect(averagingInt(Menu::getCalories))

    Joining

    String

    连接流中每个元素的toString方法生成的字符串

    示例:String name=Menu.getMenus.stream().map(Menu::getName).collect(joining(“, ”))

    maxBy

    Optional<T>

    一个包裹了流中按照给定比较器选出的最大元素的optional
    如果为空返回的是Optional.empty()

    示例:Optional<Menu> fattest=Menu.getMenus.stream().collect(maxBy(Menu::getCalories))

    minBy

    Optional<T>

    一个包裹了流中按照给定比较器选出的最大元素的optional
    如果为空返回的是Optional.empty()

    示例: Optional<Menu> lessest=Menu.getMenus.stream().collect(minBy(Menu::getCalories))

    Reducing

    归约操作产生的类型

    从一个作为累加器的初始值开始,利用binaryOperator与流中的元素逐个结合,从而将流归约为单个值

    示例:int count=Menu.getMenus.stream().collect(reducing(0,Menu::getCalories,Integer::sum));

    collectingAndThen

    转换函数返回的类型

    包裹另一个转换器,对其结果应用转换函数

    示例:Int count=Menu.getMenus.stream().collect(collectingAndThen(toList(),List::size))

    groupingBy

    Map<K,List<T>>

    根据流中元素的某个值对流中的元素进行分组,并将属性值做为结果map的键

    示例:Map<Type,List<Menu>> menuType=Menu.getMenus.stream().collect(groupingby(Menu::getType))

    partitioningBy

    Map<Boolean,List<T>>

    根据流中每个元素应用谓语的结果来对项目进行分区

    示例:Map<Boolean,List<Menu>> menuType=Menu.getMenus.stream().collect(partitioningBy(Menu::isType));


  • 相关阅读:
    操作系统、存储介质以及电信行业单位换算差异
    Luogu P1659 [国家集训队]拉拉队排练
    AC自动机
    KMP
    Luogu P1470 最长前缀 Longest Prefix
    Luogu P2292 [HNOI2004]L语言
    Manacher算法
    字典(Trie)树
    逆序对
    vs
  • 原文地址:https://www.cnblogs.com/archermeng/p/7537100.html
Copyright © 2020-2023  润新知