java 8 ラムダ式 リスト操作 グループ化、フィルタリング、合計、最多、ソート、重複排除
java 8のラムダ式は、リスト操作のための便利なメソッドを提供しています。主に、グループ化、フィルタリング、合計、ソート、重み付け解除をカバーしています。これは、従来のリストの書き方に比べて、かなり少ないコードで済みます。
新しいエンティティクラスを作成する
package com.vvvtimes.vo;
import java.math;
import java.util;
public class User {
private Long id;
//name
private String name;
//age
private int age;
//job number
private String jobNumber;
//gender
private String sex;
//entry date
private Date entryDate;
//number of family members
private BigDecimal familyMemberQuantity;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getJobNumber() {
return jobNumber;
}
public void setJobNumber(String jobNumber) {
this.jobNumber = jobNumber;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getEntryDate() {
return entryDate;
}
public void setEntryDate(Date entryDate) {
this.entryDate = entryDate;
}
public BigDecimal getFamilyMemberQuantity() {
return familyMemberQuantity;
}
public void setFamilyMemberQuantity(BigDecimal familyMemberQuantity) {
this.familyMemberQuantity = familyMemberQuantity;
}
}
1. グループ分けについて
groupingByを使用すると、特定のフィールドをグループ化することができます。
//group
Map<String, List<User>> groupBySex = userList.stream().collect(Collectors.groupingBy(User::getSex));
//Iterate through the groups
for (Map.Entry<String, List<User>> entryUser : groupBySex.entrySet()) {
String key = entryUser.getKey();
List<User> entryUserList = entryUser.getValue();
}
トップドアのグループ化にはキーヌルセキュリティの問題があり、フィルタリングまたはラッピングが必要です
オプションのレポートによるラッピング 使用中の値が存在しない
//Grouping to add cumulative
Map<Optional<Long>, List<SalesOrderMonthlyStatementVo>> groupMap = list.stream().collect(Collectors.groupingBy(x -> ; Optional.ofNullable(x.getReviewerGroupId())));
// Iterate through the groups
for (Map.Entry<Optional<Long>, List<SalesOrderMonthlyStatementVo>> entryGroup : groupMap.entrySet()) {
Optional<Long> key = entryGroup.getKey();
Long groupId = key.get();
List<SalesOrderMonthlyStatementVo> entryGroupList = entryGroup.getValue();
}
正しい使い方は、以下のように、カスタムgroupingBy_WithNullKeysを使用することです。
/* Like Collectors.groupingBy, but accepts null keys. */
public static <T, A> Collector<T, ? , Map<A, List<T>>>
groupingBy_WithNullKeys(Function<? super T, ? extends A> classifier) {
return Collectors.toMap(
classifier,
Collections::singletonList,
(List<T> oldList, List<T> newEl) -> {
List<T> newList = new ArrayList<>(oldList.size() + 1);
newList.addAll(oldList);
newList.addAll(newEl);
return newList;
});
}
次に
Map<Long, List<SalesOrderMonthlyStatementVo>> groupMap = list.stream().collect(groupingBy_WithNullKeys(x -> x. getReviewerGroupId()));
マルチフィールドグルーピング
Function<WarehouseReceiptLineBatch, List<Object>> compositeKey = wlb ->
Arrays.<Object>asList(wlb.getWarehouseReceiptLineId(), wlb.getWarehouseAreaId(), wlb.getWarehouseLocationId());
Map<Object, List<WarehouseReceiptLineBatch>> map =
warehouseReceiptLineBatchList.stream().collect(Collectors.groupingBy(compositeKey, Collectors.toList()));
//Iterate through the groups
for (Map.Entry<Object, List<WarehouseReceiptLineBatch>> entryUser : map.entrySet()) {
List<Object> key = (List<Object>) entryUser.getKey();
List<WarehouseReceiptLineBatch> entryUserList = entryUser.getValue();
Long warehouseReceiptLineId = (Long) key.get(0);
Long warehouseAreaId = (Long) key.get(1);
Long warehouseLocationId = (Long) key.get(2);
}
2. フィルタリング
filter メソッドを使用すると、特定の条件をフィルタリングすることができます
//filter
//Exclude users with work number 201901
List<User> userCommonList = userList.stream().filter(a -> !a.getJobNumber().equals("201901")).collect(Collectors. toList());
3. 和算
基本型とラージ型で合計し、基本型はmapToIntしてsumメソッドを呼び、ラージ型はreduceしてBigDecimal::addメソッドを呼びます。
//summing
//basic type
int sumAge = userList.stream().mapToInt(User::getAge).sum();
//BigDecimal summation
BigDecimal totalQuantity = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
上記のsumationでは、bigDecimalオブジェクトがNULLの場合をフィルタリングできず、NULLポインタを報告することがありますが、その場合は、filterメソッドでフィルタリングするか、sumationメソッドを書き換えます。
集計方法を書き換える
package com.vvvtimes.util;
import java.math;
public class BigDecimalUtils {
public static BigDecimal ifNullSet0(BigDecimal in) {
if (in ! = null) {
return in;
}
return BigDecimal.ZERO;
}
public static BigDecimal sum(BigDecimal . .in){
BigDecimal result = BigDecimal.ZERO;
for (int i = 0; i < in.length; i++){
result = result.add(ifNullSet0(in[i]));
}
return result;
}
}
オーバーライト方式を使用
BigDecimal totalQuantity2 = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimalUtils::sum);
オブジェクトのNULL判定
stream.filter(x -> x!=null)
stream.filter(Objects::nonNull)
stream.filter(x -> x.getDateTime()! =null)
フィールドNULLの判定
//min
Date minEntryDate = userList.stream().map(User::getEntryDate).min(Date::compareTo).get();
//max
Date maxEntryDate = userList.stream().map(User::getEntryDate).max(Date::compareTo).get();
4. ベストバリュー
min max法でminとmaxを求める。
Comparator<LeasingBusinessContract> comparator = Comparator.comparing(LeasingBusinessContract::getLeaseEndDate);
LeasingBusinessContract maxObject = leasingBusinessContractList.stream().max(comparator).get();
時には、最大値と最小値に対応するオブジェクトを知る必要がありますが、これは次のようにして得ることができます。
/**
* List -> Map
* One thing to note is.
* toMap If the collection object has duplicate keys, it will report the error Duplicate key ....
* user1,user2 id are 1.
* You can use (k1,k2)-> k1 to set, if there are duplicate keys, then keep key1, discard key2
*/
Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, a -> a,(k1,k2)->k1));
5. マップへのリスト
Map<String, WorkCenterLoadVo> workCenterMap = list.stream().collect(Collectors.toMap(key->DateFormatUtils.format(key.getDate( ), "yyyy-MM-dd"), a -> a,(k1,k2)->k1));
リストをマップに変換するとき、キーとして日付型を使うことがありますが、実際には文字列を使うことの方が多いので、フィールドを文字列に変換することができます
//Sort
//Sort by single field, sort by id
userList.sort(Comparator.comparing(User::getId));
//sort by multiple fields, sort by id, age
userList.sort(Comparator.comparing(User::getId).thenComparing(User::getAge));
list to map では、複数のフィールドキーを持つマップ構造を使うことがあります。通常のキーの文字列連結に加えて、apache commons のマップ構造 MultiKeyMap を複数のフィールドキーの形で使用することができます。
6. ソート
Sortによる単一フィールド・複数フィールドの並べ替え
userList.sort(Comparator.compare(User::getId,Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(User::getAge, Comparator.nullsLast(Comparator.naturalOrder())));
これは実際にはヌル安全性の問題があるので、次のように変更することが推奨されます。
//de-duplication
List<Long> idList = new ArrayList<Long>();
idList.add(1L);
idList.add(1L);
idList.add(2L);
List<Long> distinctIdList = idList.stream().distinct().collect(Collectors.toList());
7. 重複排除
重複排除は明確な方法で行うことができる
List<AddOutboundNoticeDetailsBatchVo> entryDetailsBatchDistinctBatchIdList = entryDetailsBatchList.stream().filter( distinctByKey(b -> b.getMaterialBatchNumberId())).collect(Collectors.toList());
//distinctByKey defined by themselves
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
属性に対して重複を排除する
// Get a field of a list object to assemble a new list
List<Long> userIdList = userList.stream().map(a -> a.getId()).collect(Collectors.toList());
8. リストのフィールドを取得し、新しいリストを組み立てる
addList.stream().forEach(a -> a.setDelFlag("0"));
9. リストのリストフィールドを同じ値に一括設定する
List<TimePeriodDate> timePeriodDateList1 = calendarModelVoList.stream().map(p->{TimePeriodDate e = new TimePeriodDate(); e. setStartDate(p.getBegin()); e.setEndDate(p.getEnd()); return e;}).collect(Collectors.toList());
10. 異なるエンティティのリストコピー
List<TimePeriodDate> timePeriodDateList1 = calendarModelVoList.stream().map(p->{TimePeriodDate e = new TimePeriodDate(); e. setStartDate(p.getBegin()); e.setEndDate(p.getEnd()); return e;}).collect(Collectors.toList());
関連
-
Java Error スレッド "AWT-EventQueue-0" で例外発生 java.lang.
-
javaの実行中に「javaの例外が発生しました」と表示された場合はどうすればよいですか?
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
jd-gui Java Exceptionが発生しました。
-
をインスタンス化することができません。
-
Javaドッキングリーダの落とし穴について終了コード -1073740940 (0xC0000374)でプロセス終了
-
SyntaxError: JSON入力の予期せぬ終了 解決策とアイデア
-
eclipse start tomcat エラー。Java Exceptionが発生しました
-
eclipse install plugin thing error: インストールするアイテムの収集中にエラーが発生しました セッションコンテキストは次のとおりです:(profil
-
原因: org.apache.maven.plugin.compiler.CompilationFailureException: コンパイルに失敗しました。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
アクセス制限について アプリケーションの種類がAPIでない(必要なライブラリの制限)。
-
アクセス制限です。タイプ 'Application' は API ではありません。
-
リソースの読み込みに失敗しました。サーバーはステータス500(内部サーバーエラー)で応答しました。
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
Java言語プログラミング(基礎編)(第10版)練習問題解答編 第7章
-
トークンの構文エラー、構成要素の誤配置 エラーの理由
-
java.security.InvalidAlgorithmParameterException: TrustAnchors パラメータは空であってはなりません 解決策
-
SpringBoot ❤ SpringClould共通アノテーションエピックまとめ
-
springSecurityセキュリティフレームワークの学習と原則の解釈
-
Intellij IDEA 実行前エラー コマンドラインが長すぎます。