簡體   English   中英

java-存儲字符串數組的唯一列表的最佳方法

[英]java - best way to store unique list of string array

我有可能有重復條目的字符串數組列表。 我想從這些值中獲得唯一列表。

我有一個字符串數組列表,每個數組都有兩個String值。

樣本字符串數組值:

{"error message 1", "fail"}
{"error message 2", "N/A"}
{"error message 1", "fail"} // duplicate
{"error message 2", "fail"}

我分別從JSON元素獲取“錯誤消息1”“失敗”字符串,並將它們添加到String數組對象中。 現在,我想要此數組的唯一組合。 因此,如果我具有上述4個數組,那么我只想擁有三個唯一條目的列表。

從互聯網搜索中,我向下鑽取以將HashSet用於我的用例(順序無關緊要)。 但是, HashSet將所有4個條目添加到集合中。 我什至嘗試使用' contains '來檢查對象是否已經存在,但這也不起作用。 我相信,這是因為contains方法正在比較“ 引用 ”而不是“ ”。 這是HashSet添加重復值的原因嗎?

我將這些String數組添加到HashSet的代碼是

Set<String[]> uniqueSet = new HashSet<String[]>();
if(!uniqueSet.contains(new String[] {errorMessage,result})) // I get errorMessage and result as separate Strings
   uniqueSet.add(new String[] {errorMessage,result}); // I expect to have only 3 values here in the uniqueSet. But it adds all 4.

從SO相關問題的答案中,我了解到,如果需要,必須重寫哈希碼相等方法。 但是,如果這正是我所缺少的,我不確定該如何處理?

另外,如果您還有其他建議可以更好地唯一存儲String數組,請告訴我。

問候,

魯米特

您可以使用List而不是數組。 如果使用java.util包中的列表,則它們應該已經以適合您需求的方式實現了hashCode()equals(Object) (深等於和深hasCode):

String[][] stringArrays = new String[][] {
    {"error message 1", "fail"},
    {"error message 2", "N/A"},
    {"error message 1", "fail"}, // duplicate
    {"error message 2", "fail"}
};

Set<List<String>> uniqueSet = new HashSet<List<String>>();
for (String[] a : stringLists) {
    uniqueSet.add(Arrays.asList(a));
}
// uniqueSet.size() should return 3 here

由於Java沒有元組,解決它的一種方法是使用元組-

class Pair<L,R> {

    private final L left;
    private final R right;


    Pair(L left, R right) {
        this.left = left;
        this.right = right;
    }

    L getLeft() {
        return left;
    }

    R getRight() {
        return right;
    }

    @Override
    public int hashCode() { return left.hashCode() ^ right.hashCode(); }

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (!(o instanceof Pair)) return false;
        Pair pairo = (Pair) o;
        return this.left.equals(pairo.getLeft()) &&
                this.right.equals(pairo.getRight());
    }

}

我不知道它是否適合您的需求,但是(至少)更快的解決方案是使用HashMap

HashMap<String, String> hashMap = new HashMap<String, String>();

hashMap.put("error message 1","fail");
hashMap.put("error message 2","fail");
hashMap.put("error message 1","N/A");

結果將只有列表中的兩個元素,因為Key元素(在這種情況下為“錯誤消息1”)將被您放入列表中的下一個元素覆蓋。

結果:

hashMap=[{"error message 1","N/A"},{"error message 2","fail"}];

代替使用Set<String[]> ,創建一個新類,例如:

public class MyError {
    private String message;
    private String detail;

    //constructors, getters and setters

    public boolean equals(Object other) {
        //implement equals here - i suggest you to use an IDE auto generated equals()
    }
}

並使用Set<MyError> 因此,當您這樣做時:

uniqueSet.add(new MyError(errorMessage, result));

由於執行equals,它將正確抑制重復的條目。

暫無
暫無

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

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