从java集合中删除重复元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20626312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove duplicate element from the set in java
提问by Manan Shah
I have set of string array and i want to remove duplicate elements from this...
我有一组字符串数组,我想从中删除重复的元素...
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new HashSet<String[]>();
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String[] {"a1","b1"});
System.out.print(mySet.size());
Currently mySet looks like this:
目前 mySet 看起来像这样:
[{"a1","b1"},{"a2","b2"},{"a1","b1"}]
But I want like this:
但我想要这样:
[{"a1","b1"},{"a2","b2"}]
I know some ways...
我知道一些方法...
- Every time I need to run inner loop and check whether its duplicate or not.
- Can I override the set's behavior? (hashcode or equals)? ( i do not know how....)
- Do I need to change data structure for this? (linkedhashset or list or any other suitable data structure for this?)
- 每次我需要运行内循环并检查它是否重复时。
- 我可以覆盖集合的行为吗?(哈希码或等于)?( 我不知道怎么....)
- 我需要为此更改数据结构吗?(linkedhashset 或 list 或任何其他合适的数据结构?)
采纳答案by c.P.u1
Arrays inherit from Object and don't override the hashCode
and equals
methods. A HashSet
uses a Map
implementation, which in turn, uses hashCode
and equals
to avoid duplicate elements.
数组继承自 Object 并且不覆盖hashCode
和equals
方法。AHashSet
使用一个Map
实现,该实现反过来使用hashCode
并equals
避免重复元素。
You can use a TreeSet
with a custom Comparator
that compares the String
arrays for equality.
您可以将 aTreeSet
与Comparator
比较String
数组的相等性的自定义一起使用。
Set<String[]> mySet = new TreeSet<>(new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
return Arrays.equals(o1, o2)? 0 : Arrays.hashCode(o1) - Arrays.hashCode(o2);
}
});
Note that this will only neglect duplicate arrays with the same corresponding elements. If the order of elements is different, it won't be considered as a duplicate.
请注意,这只会忽略具有相同对应元素的重复数组。如果元素的顺序不同,则不会被视为重复。
If you want to be able to discard unorderedduplicates, for e.g., {a1, b1}
and {b1, a1}
, use this:
如果您希望能够丢弃无序的重复项,例如,{a1, b1}
and {b1, a1}
,请使用以下命令:
@Override
public int compare(String[] o1, String[] o2) {
int comparedHash = o1.hashCode() - o2.hashCode();
if(o1.length != o2.length) return comparedHash;
List<String> list = Arrays.asList(o1);
for(String s : o2) {
if(!list.contains(s)) return comparedHash;
}
return 0;
}
回答by bcorso
The array
hashcode is independent of the contents of the array
(it inherits the Object
hashcode, which uses the array's reference).
所述array
散列码是独立的的内容array
(它继承的Object
哈希码,它使用阵列的参照)。
However, List
would do what you want. It uses a hashcode based on the elements in the List
. From Java Docs:
但是,List
会做你想做的。它使用基于List
. 来自 Java 文档:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Example:
例子:
List<String> list1 = Arrays.asList("a1","b1");
List<String> list2 = Arrays.asList("a2","b2");
Set<List<String>> mySet = new HashSet<List<String>>();
mySet.add(list1);
mySet.add(list2);
mySet.add(Arrays.asList("a1","b1")); // duplicate won't be added
System.out.print(mySet.size()); // size = 2
回答by 75inchpianist
Why not use a List implementation? The list.equals will compare elements in each list and determine equality.
为什么不使用 List 实现?list.equals 将比较每个列表中的元素并确定相等性。
List<String> arr1 = new ArrayList<String>();
arr1.add("a1");
arr1.add("b1");
List<String> arr2 = new ArrayList<String>();
arr2.add("a2");
arr2.add("b2");
Set<List<String>> mySet = new HashSet<List<String>>();
mySet.add(arr1);
mySet.add(arr2);
List<String> arr3 = new ArrayList<String>();
arr3.add("a1");
arr3.add("b1");
mySet.add(arr3);
System.out.print(mySet.size());
You suggest overriding equals and hashcode methods. HashSet is backed by a hashmap that uses the hashcode function as its key. So actually you need to override hashcode to represent your equals criteria.
您建议覆盖 equals 和 hashcode 方法。HashSet 由使用 hashcode 函数作为其键的 hashmap 支持。所以实际上你需要覆盖哈希码来表示你的等于标准。
One problem with this. I believe String and therefore String [] are declared as final, so you can't extend them :(
一个问题。我相信 String 和 String [] 被声明为 final,所以你不能扩展它们:(
回答by TheLostMind
Try something like this...
尝试这样的事情......
public static void main(String... args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new HashSet<String[]>();
mySet.add(arr1);
mySet.add(arr2);
String str[] =new String[] {"a1","b1"};
long t1 = System.nanoTime();
boolean b =checkContains(str,mySet);
long t2=System.nanoTime();
long t = t2-t1;
System.out.println("time taken : " + t );
System.out.println(b);
if(!b)
{
mySet.add(str);
}
}
public static boolean checkContains(String[] str, Set mySet)
{
Iterator it = mySet.iterator();
while(it.hasNext())
{
String[] arr = (String[])it.next();
if(arr[0].equals(str[0]) && arr[1].equals(str[1]) )
{
return true;
}
}
return false;
}
OP :
操作:
time taken : 184306
true
所用时间:184306
真的
回答by Satheesh Cheveri
Arrays uses identity-based Object.hashCode()
implementation and there is no easy way to check if they are equal. If it all you still want to go ahead with your problem I would suggest you to use TreeSet
with Comparator
数组使用identity-based Object.hashCode()
实现并且没有简单的方法来检查它们是否相等。如果您仍然想继续解决您的问题,我建议您使用 TreeSet
Comparator
Though not fail proof approach, but you should be able to build fine tuned solution out of my example,
虽然不是防故障方法,但您应该能够从我的示例中构建微调的解决方案,
public static void main(String[] args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
Set<String[]> mySet = new TreeSet<String[]>(new ArrayComparator());
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String[] {"a1","b1"});
System.out.println(mySet.size());
for(String[] aa: mySet){
System.out.println(aa[0]+" , "+aa[1]);
}
}
}
class ArrayComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
String[] ar1 =(String[]) o1;
String[] ar2 =(String[]) o2;
if(ar1.length!=ar2.length){
return -1;
}
for(int count=0;count<ar1.length;count++){
if(!ar1[count].equals(ar2[count])){
return -1;
}
}
return 0;
}
回答by Alpesh Jikadra
Here instead of keeping Set you can use Set<SomeClass> and the override the hash and equals method for the class SomeClass so it will solve your problem.
在这里,您可以使用 Set< SomeClass> 并覆盖 SomeClass 类的哈希和 equals 方法,而不是保留 Set,这样就可以解决您的问题。
回答by Pankaj Goyal
instead of taking array of string you can create a class Like this..
您可以创建一个类,而不是使用字符串数组,就像这样..
public class String1 implements Comparable<String1>{
String str1;
String str2;
public String1(String a, String b) {
str1 = a;
str2 = b;
}
public String getStr1() {
return str1;
}
}
public String getStr2() {
return str2;
}
@Override
public String toString() {
return "String1 [str1=" + str1 + ", str2=" + str2
+ "]";
}
@Override
public int compareTo(String1 o) {
if(str1.contentEquals(o.getStr1()) && str2.contentEquals(o.getStr2())) return 0 ;
return 1;
}
}
And after that insteed of string you can take this one class object. replace HashSet with TreeSet. Like this .
在那之后,你可以使用这个单一的类对象。用 TreeSet 替换 HashSet。像这样 。
String1 arr1 =new String1("a1","b1");
String1 arr2 =new String1("a2","b2");
Set<String1> mySet = new TreeSet<String1>();
mySet.add(arr1);
mySet.add(arr2);
mySet.add(new String1("a1","b1"));
System.out.print(mySet.size());
System.out.println(mySet.toString());
So this will sort as well this will check for duplicate also.
所以这也会排序,这也会检查重复项。
回答by Ravi Parsania
try to this code.............
试试这个代码…………
import java.util.HashSet;
import java.util.Set;
public class setDemo {
static Set<String[]> mySet = new HashSet<String[]>();
static Set tempSet = new HashSet();
public static void main(String[] args) {
String[] arr1 = {"a1","b1"};
String[] arr2 = {"a2","b2"};
addObject(arr1);
addObject(arr2);
addObject(new String[] {"a1","b1"});
System.out.print(mySet.size());
// System.out.println(tempSet);
}
public static void addObject(String[] o){
StringBuffer sb = new StringBuffer();
for(Object obj:o){
sb.append(obj.toString());
}
if(!tempSet.contains(sb.toString())){
tempSet.add(sb.toString());
mySet.add(o);
}
}
}