Java 如何从 ArrayList 中删除重复的元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/203984/
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
How do I remove repeated elements from ArrayList?
提问by user25778
I have an ArrayList<String>
, and I want to remove repeated strings from it. How can I do this?
我有一个ArrayList<String>
, 我想从中删除重复的字符串。我怎样才能做到这一点?
采纳答案by jonathan-stafford
If you don't want duplicates in a Collection
, you should consider why you're using a Collection
that allows duplicates. The easiest way to remove repeated elements is to add the contents to a Set
(which will not allow duplicates) and then add the Set
back to the ArrayList
:
如果您不想在 a 中出现重复项Collection
,您应该考虑为什么要使用Collection
允许重复项的 a 。删除重复元素的最简单方法是将内容添加到 a Set
(不允许重复),然后将Set
back添加到ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Of course, this destroys the ordering of the elements in the ArrayList
.
当然,这破坏了ArrayList
.
回答by Benno Richters
If you don't want duplicates, use a Setinstead of a List
. To convert a List
to a Set
you can use the following code:
如果您不想重复,请使用Set而不是List
. 要将 a 转换List
为 aSet
您可以使用以下代码:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
If really necessary you can use the same construction to convert a Set
back into a List
.
如果真的有必要,您可以使用相同的构造将 aSet
转换为List
.
回答by abahgat
Although converting the ArrayList
to a HashSet
effectively removes duplicates, if you need to preserve insertion order, I'd rather suggest you to use this variant
虽然转换ArrayList
为 aHashSet
有效地删除了重复项,但如果您需要保留插入顺序,我宁愿建议您使用此变体
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Then, if you need to get back a List
reference, you can use again the conversion constructor.
然后,如果您需要取回List
引用,您可以再次使用转换构造函数。
回答by Vinze
As said before, you should use a class implementing the Set interface instead of List to be sure of the unicity of elements. If you have to keep the order of elements, the SortedSet interface can then be used; the TreeSet class implements that interface.
如前所述,您应该使用实现 Set 接口的类而不是 List 来确保元素的唯一性。如果必须保持元素的顺序,则可以使用 SortedSet 接口;TreeSet 类实现了该接口。
回答by volley
Probably a bit overkill, but I enjoy this kind of isolated problem. :)
可能有点矫枉过正,但我喜欢这种孤立的问题。:)
This code uses a temporary Set (for the uniqueness check) but removes elements directly inside the original list. Since element removal inside an ArrayList can induce a huge amount of array copying, the remove(int)-method is avoided.
此代码使用临时 Set(用于唯一性检查)但直接删除原始列表中的元素。由于在 ArrayList 中删除元素会导致大量的数组复制,因此避免使用 remove(int) 方法。
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
While we're at it, here's a version for LinkedList (a lot nicer!):
当我们在做的时候,这里有一个 LinkedList 版本(更好!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Use the marker interface to present a unified solution for List:
使用marker接口为List呈现统一的解决方案:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: I guess the generics-stuff doesn't really add any value here.. Oh well. :)
编辑:我猜泛型的东西在这里并没有真正增加任何价值..哦。:)
回答by stbn
Here's a way that doesn't affect your list ordering:
这是一种不会影响您的列表排序的方法:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 is the original list, and l2 is the list without repeated items (Make sure YourClass has the equals method according to what you want to stand for equality)
l1 是原始列表,l2 是没有重复项的列表(确保 YourClass 根据您要代表的相等性具有 equals 方法)
回答by HarpyWar
When you are filling the ArrayList, use a condition for each element. For example:
填充 ArrayList 时,请为每个元素使用一个条件。例如:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
We will get an array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
我们将得到一个数组 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
回答by Timofey Gorshkov
There is also ImmutableSet
from Guavaas an option (hereis the documentation):
也有ImmutableSet
来自Guava的选项(这里是文档):
ImmutableSet.copyOf(list);
回答by Ghyour
for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}
回答by reddy
import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}