Use of lambda expressions (full)

Everyone should know the lambda expression of jdk8, it is still relatively easy to use, the usage is introduced below

Introduction to Lambda

Lambda expressions are a new feature of JDK8, which can replace most of the anonymous inner classes and write more elegant Java code, especially in the traversal of collections and other collection operations, which can greatly optimize the code structure.
JDK also provides a large number of built-in functional interfaces for us to use, making the use of Lambda expressions more convenient and efficient.
The grammatical form is () -> {}, where () is used to describe the parameter list, {} is used to describe the method body, and -> is the lambda operator, pronounced (goes to).

Streams

Stream has several characteristics:

  • Stream does not store data, but calculates the data according to specific rules, and generally outputs the result.
  • Stream does not change the data source, and usually generates a new set or a value.
  • Stream has a delayed execution feature, and the intermediate operation will only be executed when the terminal operation is called.

(Use collect when gathering, and use map when operating on objects)

Match

stringList.sort((a,b)->a.compareTo(b));  //排序
boolean ret = stringList.stream().anyMatch(x->x.startsWith("a"));  

match

anyMatch means that any element
in the judgment condition is successful and returns true. AllMatch means that all elements in the judgment condition are all true
. NoneMatch is the opposite of allMatch. If all elements in the judgment condition are not, it returns true.

Filter/count

long num = stringList.stream().filter(x->x.startsWith("b")).count();
List<Integer> list = Arrays.asList(3,2,67,9,1);
Integer i = list.stream().min(Integer::compareTo).get();

Sum

double total = accountList.stream().mapToDouble(Account::getBalance).sum();

Parallel Streams

Parallel stream is faster than serial stream, but you need to pay attention to whether there is data disorder in the usage scenario. So when to use parallelStream?

  • Note whether the list elements can be processed in parallel?
  • Are the elements independent?
  • Is there a distinction between calling order?
  • If there are none, you can use this stream more quickly
//对象TestDTO
Map<String, List<TestDTO>> sortAppId = list.parallelStream().collect(
Collectors.groupingBy(TestDTO::getAppId));
//appid为对象的一个属性

//可用大括号具体操作
list.parallelStream().map(x -> {
    x.setOrderId(1);
    return x;
}).collect(Collectors.toList());

asynchronous

public static void sync() throws Exception {
//异步执行
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
        }
        if(new Random().nextInt()%2>=0) {
            int i = 12/0;
        }
        System.out.println("run end ...");
    });
    
//异步完成回调
    future.whenComplete(new BiConsumer<Void, Throwable>() {
        @Override
        public void accept(Void t, Throwable action) {
            System.out.println("执行完成!");
        }
        
    });

//异步异常回调
    future.exceptionally(new Function<Throwable, Void>() {
        @Override
        public Void apply(Throwable t) {
            System.out.println("执行失败!"+t.getMessage());
            return null;
        }
    });
    
    TimeUnit.SECONDS.sleep(2);
}

Use of map

List<Employee> employees = initList();

List<Integer> employeeList = employees.stream().map(Employee::getId)
.collect(toList());

//提取为Map1
Map<Integer, Employee> idEmployeeMap = employees.stream().collect(
Collectors.toMap(Employee::getId, Function.identity()));

//提取为map2,value为List
Map<Integer, List<Employee>> departGroupMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartId));

//提取为map3,value为list下对象中的一个字段的集合
Map<Integer, List<String>> departNamesMap =employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartId,
Collectors.mapping(Employee::getName, Collectors.toList()))
);

//获取一个属性的集合
List<String> workIds = list.parallelStream().map(TestDTO::getWorkId)
.collect(Collectors.toList());


/**
 * List -> Map
 * 需要注意的是:
 * toMap 如果集合对象有重复的key,会报错Duplicate key ....
 *  apple1,apple12的id都为1。
 *  可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
 */
Map<Integer, Apple> appleMap = appleList.stream().collect(
Collectors.toMap(Apple::getId, a -> a,(k1,k2)->k1));

max use

Optional<Person> max = personList.stream()
    .max(Comparator.comparingInt(Person::getSalary));

stream reduction

Multiple in one

public class StreamTest {
 public static void main(String[] args) {
  List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
  // 求和方式1
  Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
  // 求和方式2
  Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
  // 求和方式3
  Integer sum3 = list.stream().reduce(0, Integer::sum);
  
  // 求乘积
  Optional<Integer> product = list.stream().reduce((x, y) -> x * y);

  // 求最大值方式1
  Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
  // 求最大值写法2
  Integer max2 = list.stream().reduce(1, Integer::max);

  System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);
  System.out.println("list求积:" + product.get());
  System.out.println("list求和:" + max.get() + "," + max2);
 }
}


// 求工资之和方式1:
Optional<Integer> sumSalary = personList.stream().map(Person::getSalary)
  .reduce(Integer::sum);
  
// 求工资之和
  Integer sum = personList.stream()
  .collect(Collectors.summingInt(Person::getSalary));


  // 求最高工资方式1:
Integer maxSalary = personList.stream()
      .reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
    Integer::max);
    
    // 求最高工资
Optional<Integer> max = personList.stream().map(Person::getSalary)
  .collect(Collectors.maxBy(Integer::compare));

Collectors

Collectors provides a series of static methods for data statistics:

Count: count

平均值:averagingInt、averagingLong、averagingDouble

Maximum value: maxBy, minBy

Sum: summingInt, summingLong, summingDouble

Count all the above: summarizingInt, summarizingLong, summarizingDouble

// 求平均工资
  Double average = personList.stream()
  .collect(Collectors.averagingDouble(Person::getSalary));


// 一次性统计所有信息
DoubleSummaryStatistics collect = personList.stream()
.collect(Collectors.summarizingDouble(Person::getSalary));

返回
DoubleSummaryStatistics{count=3, sum=23700.000000,min=7000.000000, average=7900.000000, max=8900.000000}

Grouping

将员工按薪资是否高于8000分组
Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
// 将员工按性别分组
Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
// 将员工先按性别分组,再按地区分组
Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.
    groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));

Joining

//用逗号给集合中的名字连接起来
String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));

Collectors' reduction

Compared with the reduce method of stream itself, support for custom reduction is added.

Sorted

There are two sorts:

  • sorted(): Natural sorting, the elements in the stream need to implement the Comparable interface
  • sorted (Comparator com): Comparator sorter custom sorting
stringList.stream().map(String::toUpperCase).sorted((a,b)->a.compareTo(b)).forEach(System.out::println); 

// 按工资增序排序
List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
    .collect(Collectors.toList());
// 按工资倒序排序
List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
    .map(Person::getName).collect(Collectors.toList());

De-duplication

stream().map(YxStoreProduct::getProductServerId).distinct().collect(Collectors.toList());

Reference: https://mp.weixin.qq.com/s/WM4IfFcEilY3dGTfa2ap9g

Guess you like

Origin blog.csdn.net/Goligory/article/details/113835505