Java8必知必会

    xiaoxiao2021-03-25  58

    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));

    转载请注明原文地址: https://ju.6miu.com/read-37391.html

    最新回复(0)