ラムダ式の使用(フル)

誰もがjdk8のラムダ式を知っている必要がありますが、それでも比較的使いやすいです。使用法を以下に紹介します。

Lambdaの概要

ラムダ式はJDK8の新機能であり、匿名の内部クラスのほとんどを置き換え、特にコレクションやその他のコレクション操作のトラバーサルで、コード構造を大幅に最適化できる、より洗練されたJavaコードを記述できます。
JDKには、使用できる組み込み関数型インターフェースも多数用意されているため、Lambda式をより便利かつ効率的に使用できます。
文法形式は()-> {}です。ここで、()はパラメーターリストを説明するために使用され、{}はメソッド本体を説明するために使用され、->はラムダ演算子であり、発音されます(に移動します)。

ストリーム

ストリームにはいくつかの特徴があります。

  • Streamはデータを格納しませんが、特定のルールに従ってデータを計算し、通常は結果を出力します。
  • ストリームはデータソースを変更せず、通常は新しいセットまたは値を生成します。
  • ストリームには遅延実行機能があり、中間操作は端末操作が呼び出されたときにのみ実行されます。

(収集する場合は収集を使用し、オブジェクトを操作する場合はマップを使用します)

一致

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

一致

anyMatchは
、判定条件のすべての要素が成功し、trueを返すことを意味します。AllMatchは、判定条件のすべての要素がすべてtrueであることを意味し
ます。NoneMatchはallMatchの反対です。判定条件のすべての要素がそうでない場合、trueを返します。

フィルタ/カウント

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

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

並列ストリーム

パラレルストリームはシリアルストリームよりも高速ですが、使用シナリオにデータの乱れがあるかどうかに注意する必要があります。では、いつparallelStreamを使用するのですか?

  • リスト要素を並行して処理できるかどうかに注意してください。
  • 要素は独立していますか?
  • 呼び出し順序に違いはありますか?
  • ない場合は、このストリームをより迅速に使用できます
//对象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());

非同期

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

地図の使用

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

最大使用

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

ストリーム削減

1つに複数

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

コレクター

コレクターは、データ統計のための一連の静的メソッドを提供します。

カウント:カウント

平均值:averagingInt、averagingLong、averagingDouble

最大値:maxBy、minBy

合計:summingInt、summingLong、summingDouble

上記のすべてを数えます: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}

グループ化

将员工按薪资是否高于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)));

接合

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

コレクターの削減

ストリーム自体のreduceメソッドと比較して、カスタム削減のサポートが追加されています。

ソート済み

2つの種類があります:

  • sort():自然ソート、ストリーム内の要素はComparableインターフェースを実装する必要があります
  • ソート済み(コンパレータcom):コンパレータソータカスタムソート
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());

重複排除

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

参照:https://mp.weixin.qq.com/s/WM4IfFcEilY3dGTfa2ap9g

おすすめ

転載: blog.csdn.net/Goligory/article/details/113835505