Map<String, String> phoneBook=people.stream()
.collect(toMap(Person::getName, Person::getAddress));
重複が発生すると重複キー例外が発生します。
重複が発生したときにマップする値を追加するのを無視することは可能ですか?
重複がある場合は、その重複キーを無視して続行するだけです。
これは、 Collectors.toMap(keyMapper, valueMapper, mergeFunction)
のmergeFunction
パラメータを使用することで可能になります。
Map<String, String> phoneBook =
people.stream()
.collect(Collectors.toMap(
Person::getName,
Person::getAddress,
(address1, address2) -> {
System.out.println("duplicate key found!");
return address1;
}
));
mergeFunction
は、同じキーに関連付けられている2つの値を操作する関数です。 adress1
は、要素の収集時に検出された最初のアドレスに対応し、adress2
は、検出された2番目のアドレスに対応します。このラムダは、最初のアドレスを保持するように指示し、2番目のアドレスを無視します。
JavaDocs で述べたように、
マッピングされたキーに重複が含まれている場合(
Object.equals(Object)
に従って)、コレクション操作が実行されるとIllegalStateException
がスローされます。マッピングされたキーが重複している可能性がある場合は、代わりにtoMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)
を使用してください。
そのため、代わりに toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)
を使用してください。マージ機能を提供するだけで、どの重複部分をマップに入れる必要があるかが決まります。例えば、あなたがどちらを気にしないのであれば、ただ電話してください。
Map<String, String> phoneBook = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAddress, (a1, a2) -> a1));
@alasterの回答は私には非常に役立ちますが、誰かが情報をグループ化しようとしている場合、私は意味のある情報を追加したいと思います。
たとえば、同じOrders
だがそれぞれの製品のcode
が異なる2つのquantity
があり、希望がsumである場合、行う:
List<Order> listQuantidade = new ArrayList<>();
listOrders.add(new Order("COD_1", 1L));
listOrders.add(new Order("COD_1", 5L));
listOrders.add(new Order("COD_1", 3L));
listOrders.add(new Order("COD_2", 3L));
listOrders.add(new Order("COD_3", 4L));
listOrders.collect(Collectors.toMap(Order::getCode, o -> o.getQuantity(), (o1, o2) -> o1 + o2));
結果:
{COD_3=4, COD_2=3, COD_1=9}
私はオブジェクトをグループ化するときにこのような問題に遭遇しました、私はいつも簡単な方法でそれらを解決しました:ジャバラとしてあなたの選択のどんな属性でも重複オブジェクトを取り除くためにJava.util.Setを使ってカスタムフィルタを実行してください
Set<String> uniqueNames = new HashSet<>();
Map<String, String> phoneBook = people
.stream()
.filter(person -> person != null && !uniqueNames.add(person.getName()))
.collect(toMap(Person::getName, Person::getAddress));
これが同じ問題を抱えている人に役立つことを願っています!
あなたが人を持っていると仮定するとオブジェクトのリスト
Map<String, String> phoneBook=people.stream()
.collect(toMap(Person::getName, Person::getAddress));
今、あなたは2つのステップを必要とします:
1)
people =removeDuplicate(people);
2)
Map<String, String> phoneBook=people.stream()
.collect(toMap(Person::getName, Person::getAddress));
これは重複を削除する方法です。
public static List removeDuplicate(Collection<Person> list) {
if(list ==null || list.isEmpty()){
return null;
}
Object removedDuplicateList =
list.stream()
.distinct()
.collect(Collectors.toList());
return (List) removedDuplicateList;
}
完全な例をここに追加する
package com.example.khan.vaquar;
import Java.util.Arrays;
import Java.util.Collection;
import Java.util.List;
import Java.util.Map;
import Java.util.stream.Collectors;
public class RemovedDuplicate {
public static void main(String[] args) {
Person vaquar = new Person(1, "Vaquar", "Khan");
Person zidan = new Person(2, "Zidan", "Khan");
Person zerina = new Person(3, "Zerina", "Khan");
// Add some random persons
Collection<Person> duplicateList = Arrays.asList(vaquar, zidan, zerina, vaquar, zidan, vaquar);
//
System.out.println("Before removed duplicate list" + duplicateList);
//
Collection<Person> nonDuplicateList = removeDuplicate(duplicateList);
//
System.out.println("");
System.out.println("After removed duplicate list" + nonDuplicateList);
;
// 1) solution Working code
Map<Object, Object> k = nonDuplicateList.stream().distinct()
.collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
System.out.println("");
System.out.println("Result 1 using method_______________________________________________");
System.out.println("k" + k);
System.out.println("_____________________________________________________________________");
// 2) solution using inline distinct()
Map<Object, Object> k1 = duplicateList.stream().distinct()
.collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
System.out.println("");
System.out.println("Result 2 using inline_______________________________________________");
System.out.println("k1" + k1);
System.out.println("_____________________________________________________________________");
//breacking code
System.out.println("");
System.out.println("Throwing exception _______________________________________________");
Map<Object, Object> k2 = duplicateList.stream()
.collect(Collectors.toMap(s1 -> s1.getId(), s1 -> s1));
System.out.println("");
System.out.println("k2" + k2);
System.out.println("_____________________________________________________________________");
}
public static List removeDuplicate(Collection<Person> list) {
if (list == null || list.isEmpty()) {
return null;
}
Object removedDuplicateList = list.stream().distinct().collect(Collectors.toList());
return (List) removedDuplicateList;
}
}
// Model class
class Person {
public Person(Integer id, String fname, String lname) {
super();
this.id = id;
this.fname = fname;
this.lname = lname;
}
private Integer id;
private String fname;
private String lname;
// Getters and Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
@Override
public String toString() {
return "Person [id=" + id + ", fname=" + fname + ", lname=" + lname + "]";
}
}
結果 :
Before removed duplicate list[Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=3, fname=Zerina, lname=Khan], Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=1, fname=Vaquar, lname=Khan]]
After removed duplicate list[Person [id=1, fname=Vaquar, lname=Khan], Person [id=2, fname=Zidan, lname=Khan], Person [id=3, fname=Zerina, lname=Khan]]
Result 1 using method_______________________________________________
k{1=Person [id=1, fname=Vaquar, lname=Khan], 2=Person [id=2, fname=Zidan, lname=Khan], 3=Person [id=3, fname=Zerina, lname=Khan]}
_____________________________________________________________________
Result 2 using inline_______________________________________________
k1{1=Person [id=1, fname=Vaquar, lname=Khan], 2=Person [id=2, fname=Zidan, lname=Khan], 3=Person [id=3, fname=Zerina, lname=Khan]}
_____________________________________________________________________
Throwing exception _______________________________________________
Exception in thread "main" Java.lang.IllegalStateException: Duplicate key Person [id=1, fname=Vaquar, lname=Khan]
at Java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.Java:133)
at Java.util.HashMap.merge(HashMap.Java:1253)
at Java.util.stream.Collectors.lambda$toMap$58(Collectors.Java:1320)
at Java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.Java:169)
at Java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.Java:948)
at Java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.Java:481)
at Java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.Java:471)
at Java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.Java:708)
at Java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.Java:234)
at Java.util.stream.ReferencePipeline.collect(ReferencePipeline.Java:499)
at com.example.khan.vaquar.RemovedDuplicate.main(RemovedDuplicate.Java:48)