簡體   English   中英

在兩個對象數組列表中查找唯一字符串

[英]Finding unique strings in two arraylists of objects

我有兩個對象的數組列表,我想知道哪些字符串對於數組列表 1 是唯一的,哪些字符串對於數組列表 2 是唯一的。我想出的是下面的 forloop,我必須實現兩次,反轉位置數組列表。 我希望有人可以建議一種更優雅的方法來做到這一點。

每個請求,我猜我錯誤地認為代碼片段本身隱含了更多的東西。 這產生的輸出是:

第二個 arrayList 中不存在葡萄

菠蘿在第一個 arrayList 中不存在

效果很好,一切都很好,但是,如上所述,我希望對流/Java 有更多了解的人可以提供更好的解決方案,而不僅僅是運行我的流兩次,輸入相反。

import java.util.ArrayList;

public class CompareTwoArrays {

    ArrayList<MyCustomObject> firstArrayListOfObjects = new ArrayList<>();
    ArrayList<MyCustomObject> secondArrayListOfObjects = new ArrayList<>();

    public void superSpecificExampleMethod() {
        firstArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
        firstArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
        firstArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));
        firstArrayListOfObjects.add(new MyCustomObject(1, 1, "grape"));
        secondArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
        secondArrayListOfObjects.add(new MyCustomObject(1, 1, "pineapple"));
        secondArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
        secondArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));

        for (MyCustomObject object : firstArrayListOfObjects) {
            if (!secondArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
                System.out.println(object.getString() + " doesn't exist in second arrayList");
            }
        }

        for (MyCustomObject object : secondArrayListOfObjects) {
            if (!firstArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
                System.out.println(object.getString() + " doesn't exist in first arrayList");
            }
        }
    }
}

class MyCustomObject {

    private int randomIntOne;
    private int randomIntTwo;
    private String string;

    public MyCustomObject(int randomIntOne, int randomIntTwo, String string) {
        this.randomIntOne = randomIntOne;
        this.randomIntTwo = randomIntTwo;
        this.string = string;
    }

    public String getString() {
        return string;
    }
}

假設有兩個包含字符串的對象MyObject數組列表:

List<MyObject> listOne = new ArrayList<>(Arrays.asList(
    new MyObject("aaa"), new MyObject("bbb"), new MyObject("ccc"), new MyObject("ddd")
));

List<MyObject> listTwo = new ArrayList<>(Arrays.asList(
    new MyObject("fff"), new MyObject("bbb"), new MyObject("ggg"), new MyObject("ddd")
));

要在listOne中找到那些在listTwo中不可用的“唯一”對象,有幾種方法:

  1. 使用List::removeAll提供方法equalshashCode在此類中正確實現

removeAll應該應用於listOne的副本

List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeAll(listTwo); // ["aaa", "ccc"]
  1. 使用List::removeIf接受一個謂詞並使用包含在listTwo對象中的一組字符串:
Set<String> listTwoStrings = listTwo
    .stream()
    .map(MyObject::getString)
    .collect(Collectors.toSet);
List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeIf(x -> listTwoStrings.contains(x.getString()));
  1. 使用 Stream API filtercollect - 此處不需要副本,但使用了一組臨時字符串
List<MyObject> diffOneMinusTwo = listOne
        .stream()
        .filter(x -> !listTwoStrings.contains(x.getString()))
        .collect(Collectors.toList());

在 Java 11 中有靜態Predicate::not方法,因此流版本可能如下所示(如果hashCodeequals正確實現):

List<MyObject> diffOneMinusTwo = listOne
        .stream()
        .filter(Predicate.not(listTwo::contains)) // using method reference
        .collect(Collectors.toList());

listTwolistOne之間的差異可以反過來創建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM