我有可能有重复条目的字符串数组列表。我想从这些值中获取唯一的列表。
我有一个字符串数组列表,每个数组都有两个String值。
示例字符串数组值:
{"error message 1", "fail"}
{"error message 2", "N/A"}
{"error message 1", "fail"} // duplicate
{"error message 2", "fail"}
我单独从JSON元素中获取"错误消息1" 和"失败" 字符串,然后将其添加到字符串数组对象。现在我想要这个数组的独特组合。所以,如果我有上面的4个数组,我想只列出三个唯一的条目。
从互联网搜索中,我深入研究使用 HashSet 作为我的用例(顺序无关紧要)。但是, HashSet 会将所有4个条目添加到集合中。我甚至尝试使用' 包含'检查对象是否已存在,但这也不起作用。我相信,这是因为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数组,请告诉我。
此致
Rumit
答案 0 :(得分:7)
您可以使用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
答案 1 :(得分:1)
由于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());
}
}
答案 2 :(得分:0)
我不知道它是否符合您的需求,但(至少)更快的解决方案是使用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"}];
答案 3 :(得分:0)
创建一个新类,而不是使用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实现,它将正确地抑制重复的条目。