ストリーム処理をすぐに始めるためのベスト プラクティス | JD Logistics テクニカル チーム

I.はじめに

JAVA1.8 は Lambda によってもたらされた関数型プログラミングの恩恵を受けており、新しい Stream 概念を導入しています。Stream 概念は工場現場の "生産組立ライン" に似ています。Stream ストリームはデータ構造ではなく、データを保存しません。データの処理です。ストリームは組み立てライン上のプロセスとみなすことができます。組立ラインでは、原材料が複数の工程を経て製品に加工されます。

よく使用される 2 つの方法の紹介

2.1 ストリームストリームの取得

すべての Collection コレクションは、ストリームのデフォルト メソッドを通じてストリームを取得できます。

デフォルトのメソッド ストリームは、ストリームを取得するために java.util.Collection インターフェイスに追加されるため、そのすべての実装クラスがストリームを取得できるようになります。

ArrayList<XyBug> xyBugList = new ArrayList();
Stream<XyBug> stream = xyBugList.stream();


Streamインターフェースのstaticメソッドでは、配列に対応したストリームを取得できます。

//String
Stream<String> stream = Stream.of("aa", "bb", "cc");
//数组
String[] arr = {"aa", "bb", "cc"};
Stream<String> stream7 = Stream.of(arr);
Integer[] arr2 = {11, 22, 33};
Stream<Integer> stream8 = Stream.of(arr2);
//对象
XyBug xyBug1 = new XyBug();
XyBug xyBug2 = new XyBug();
XyBug xyBug3 = new XyBug();
Stream<XyBug> bugStream = Stream.of(xyBug1, xyBug2, xyBug3);



2.2 ストリームデータの一般的な処理方法

各メソッドごとに

このメソッドは Consumer インターフェイス関数を受け取り、各ストリーム要素をこの関数に渡して処理します。

List<String> list = new ArrayList<>();
Collections.addAll(list, "str1", "str2", "str3", "str4", "str5", "str6");
list.stream().forEach((String s) -> {
  System.out.println(s);
  });
//简写
list.stream().forEach(s -> System.out.println(s));


s はリスト内の各要素を表し、ストリーミング処理は各要素を順番に走査します。

-> その後のコードは各要素のロジックを処理します

カウント方法

countメソッドは要素数をカウントし、戻り値はlong型になります。

long count = list.stream().count();


個別のメソッド

ストリーム内のデータに対して重複排除操作を実行します。一般的なタイプは直接重複排除できます。

//将22、33重复数据去除
Stream.of(22, 33, 22, 11, 33).distinct().collect(Collectors.toList());


カスタム タイプは、オブジェクトの hashCode と同等の値に基づいて重複した要素を削除します。

XyBugエンティティクラスに@Dataアノテーションを追加すると、hashCodeとequalsが別々に書き換えられ、distinctメソッド使用時に重複排除が判定されるようになります。

ArrayList bugList = JSON.parseObject(bugs, ArrayList.class);
ArrayList<XyBug> xyBugList = new ArrayList();
List collect = (List) bugList.stream().distinct().collect(Collectors.toList());


distinct() メソッドを使用して重複を削除し、collect(Collectors.toList()) を使用して重複排除後に 6 つの新しいリストを形成します。

リミットメソッド

このメソッドはストリームをインターセプトし、最初の n 項目のみを使用できます。パラメーターは long 型です。コレクションの現在の長さがパラメーターより大きい場合、コレクションはインターセプトされます。それ以外の場合、操作は実行されません

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5", "6");
List<String> collect = list.stream().limit(3).collect(Collectors.toList());


最初の 3 つの String オブジェクトをインターセプトして新しいリストを形成します

スキップメソッド

最初のいくつかの要素をスキップしたい場合は、skip メソッドを使用してインターセプト後に新しいストリームを取得できます。ストリームの現在の長さが n より大きい場合は、最初の n 要素をスキップします。それ以外の場合は、空のストリームが取得されます。長さ0の

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5", "6");
List<String> collect = list.stream().skip(3).collect(Collectors.toList());


最初の 3 つの String オブジェクトをスキップし、最後の 3 つで新しいリストを作成します。

フィルタ方式

フィルターは、データをフィルターし、フィルター条件を満たすデータを返すために使用されます。フィルター メソッドを使用して、ストリームを別のサブセット ストリームに変換できます。このインターフェイスは、フィルタリングとして Predicate 関数インターフェイス パラメーター (Lambda またはメソッド参照にすることができます) を受け取ります状態。

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "22", "3", "4", "55", "6");
//filter方法中写入筛选条件,将过滤后的数据组成新的list
list.stream().filter(s -> s.length() == 2).collect(Collectors.toList());


このステートメントにより、s -> s.length() == 2、22、および 55 が除外されます。

マップメソッド

ストリーム内の要素を別のストリームにマッピングすると、現在のストリームの T 型データを別の R 型ストリームに変換できます

List<PersonCrDto> laputaCrDtos = queryListLaputaByBeginEndTime(begin, end);
//将list中的PersonCrDto对象的userName属性取到,收集成set集合
laputaCrDtos.stream().map(PersonCrDto::getUserName).collect(Collectors.toSet())


リスト内の各オブジェクトの userName データを取得して Set コレクションを形成します

ストリームのグループ化

List<XyBug> list = new ArrayList<>();
Map<String, List<XyBug>> collect = list.stream().collect(Collectors.groupingBy(XyBug::getBugType));


バグの種類に応じてグループ化します。グループ化後、マップが作成されます。キーはグループ名、値はグループ内のデータです。

ストリームソート

sort()、デフォルトは順方向、逆方向にソートするには reversed() メソッドを追加します。

List<XyBug> list = new ArrayList<>();
//根据createTime正序排列
List<XyBug> collect = list.stream().sorted(Comparator.comparing(XyBug::getCreateTime)).collect(Collectors.toList());
//根据createTime倒叙排列
List<XyBug> collect = list.stream().sorted(Comparator.comparing(XyBug::getCreateTime).reversed()).collect(Collectors.toList());



収集メソッド

処理されたデータをリストに収集します。collect(Collectors.toList())

処理されたデータを設定どおりに収集し、collect(Collectors.toSet())

特定のフィールド値マップに従ってデータをグループ化し、収集します (Collectors.groupingBy(o -> o.value())))

3つの実践例

要件: バグ データを orgTierName ごとにグループ化し、マップに保存する

Streamを使わないのでforループを使って色々判断する必要があり、コード行数も多くなります。

HashMap<String, List<XyBug>> map = new HashMap<>();
for (XyBug one : bugList){
    if(one.getOrgTierName() != null){
        if(map.get(one.getOrgTierName()) == null){
            List<XyBug> list = new ArrayList();
            list.add(one);
            map.put(one.getOrgTierName(),list);
        }else {
            map.get(one.getOrgTierName()).add(one);
        }
    }
}


Stream を使用すると、1 行のコードで直感的かつ効率的に実行できます。

collectDeptBugMap = bugList.stream().filter(o -> o.getOrgTierName() != null).collect(Collectors.groupingBy(o -> o.getOrgTierName()));


4つのまとめ

Stream は Collection オブジェクトの機能を強化したもので、コレクション オブジェクトに対してさまざまな非常に便利で効率的な集計操作を実行したり、大規模なデータ操作を実行したりして、プログラミングの効率、単純さ、プログラムの読みやすさを向上させることができます。この記事では、簡単な例を通じて、読者がストリーム処理をすぐに使い始めるのに役立つことを願っています。ストリーム処理関数は非常に強力です。その他のメソッドについては、API ドキュメントを参照してください。

著者: JD Logistics 楊 京平

出典:JD Cloud Developer Community Ziyuanqishuo Tech 転載の際は出典を明記してください

Bunが正式バージョン1.0をリリース、 JavaScriptがZigによって書かれたランタイム時の Windowsファイルエクスプローラーの魔法のバグ、1秒でパフォーマンスが向上 JetBrainsがRust IDEをリリース:RustRover PHPの最新統計:市場シェアは70%を超え、CMSの王様が Pythonプログラムを移植Mojo、パフォーマンスは 250 倍向上し、C よりも高速です 。.NET 8 のパフォーマンスは大幅に向上し、.NET 7 をはるかに上回っています。 JS の 3 つの主要なランタイム: Deno、Bun、Node.js の比較 Visual Studio Code 1.82 NetEase Fuxi は従業員の「バグのため人事に脅されて亡くなった」に応じました。 Unity エンジンは来年からゲームのインストール数に応じて課金されるようになります (ランタイム料金)。
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4090830/blog/10110405