如何从数组列表中删除重复元素?

我有一个ArrayList<String>,我想从它删除重复的字符串。我该怎么做呢?

949855 次浏览

如果您不希望在Collection中有重复,那么您应该考虑为什么要使用允许重复的Collection。删除重复元素最简单的方法是将内容添加到Set(不允许重复),然后将Set添加回ArrayList:

Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);

当然,这破坏了ArrayList中元素的顺序。

如果你不想重复,使用而不是List。要将List转换为Set,您可以使用以下代码:

// list is some List of Strings
Set<String> s = new HashSet<String>(list);

如果确实有必要,您可以使用相同的结构将Set转换回List

虽然将ArrayList转换为HashSet可以有效地删除重复,但如果您需要保留插入顺序,我宁愿建议您使用这个变体

// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);

然后,如果需要返回List引用,可以再次使用转换构造函数。

如前所述,应该使用实现Set接口的类而不是List来确保元素的唯一性。如果必须保持元素的顺序,则可以使用SortedSet接口;TreeSet类实现了该接口。

可能有点夸张,但我喜欢这种孤立的问题。:)

这段代码使用了一个临时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);
}
}

说到这里,下面是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();
}
}
}

使用标记界面为List提供统一的解决方案:

public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}

编辑:我猜泛型的东西并没有真正增加任何价值在这里。哦。:)

这里有一个不影响列表排序的方法:

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是原始列表,l2是没有重复项的列表 (确保你的类有equals方法,根据你想要代表的相等)

填充数组列表时,为每个元素使用一个条件。例如:

    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 + " ");
}

我们将得到一个数组{0,1,2,3,4,5,6,7,8,9,10}

还有ImmutableSet番石榴作为一个选项(在这里是文档):

ImmutableSet.copyOf(list);
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--;
}
}
}
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);
}




}
}

LinkedHashSet可以做到这一点。

String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);


System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());

/ /输出:5、1、2、3、4

public Set<Object> findDuplicates(List<Object> list) {
Set<Object> items = new HashSet<Object>();
Set<Object> duplicates = new HashSet<Object>();
for (Object item : list) {
if (items.contains(item)) {
duplicates.add(item);
} else {
items.add(item);
}
}
return duplicates;
}

这样可以解决以下问题:

private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {


Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
如果你想保留你的Order,那么最好使用LinkedHashSet。 因为如果你想通过迭代将这个列表传递给一个插入查询,顺序将被保留

试试这个

LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);

当您想返回List而不是Set时,这种转换将非常有用。

不使用HashSet还有一个数组列表也可以从arraylist中删除重复项。

试试这段代码..

    ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");


System.out.println("Duplicates List "+lst);


Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}


System.out.println("Distinct List "+lst);

输出是

Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]

在Java 8中:

List<String> deduped = list.stream().distinct().collect(Collectors.toList());

请注意,列表成员的hashCode-equals契约应该得到尊重,以便过滤正常工作。

    ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");


for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);


if(b==unique.add(value))
dup.add(value);
else
unique.add(value);




}
System.out.println(unique);
System.out.println(dup);

如果你想从ArrayList中删除重复项意味着找到下面的逻辑,

public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}


for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}


long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}

这三行代码可以从ArrayList或任何集合中删除重复的元素。

List<Entity> entities = repository.findByUserId(userId);


Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);

代码:

List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);

当然,会有内存开销。

@jonathan-stafford的解决方案是可以的。但这并没有保持列表的顺序。

如果你想保留列表的顺序,你必须使用这个:

public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator();    iter.hasNext(); ) {
Object element = iter.next();
if (set.add((T) element))
newList.add((T) element);
}
list.clear();
list.addAll(newList);
}

这只是为了完成答案。很好!

        List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);


output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
Java 8流提供了一种从列表中删除重复元素的非常简单的方法。使用不同的方法。 如果我们有一个城市列表,我们想要从该列表中删除重复的城市,可以在一行中完成-

 List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");


cityList = cityList.stream().distinct().collect(Collectors.toList());

如何从数组列表中删除重复的元素

public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}

以下是我的答案,不使用任何其他数据结构,如set或hashmap等。

public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {


ArrayList <T> uniqueArrayList = new ArrayList<T>();
for (int i = 0; i < myList.size(); i++){
if (!uniqueArrayList.contains(myList.get(i))){
uniqueArrayList.add(myList.get(i));
}
}


return uniqueArrayList;
}

在Java中,List允许对其元素进行有序访问。它们可以有重复,因为它们的查找键是位置而不是一些哈希代码,每个元素都可以被修改,而它们仍然在列表中,因为Set表示唯一元素的集合,而元素在Set中,它们不能被修改。虽然没有限制阻止您修改集合中的元素,但如果一个元素被修改,那么它可能永远丢失在集合中。

public static void main(String[] args) {
List<String> l = new ArrayList<String>();
l.add("A");
l.add("B");
l.add("C");
l.add("A");
System.out.println("Before removing duplicates: ");
for (String s : l) {
System.out.println(s);
}
Set<String> set = new HashSet<String>(l);
List<String> newlist = new ArrayList<String>(set);
System.out.println("after removing duplicates: ");
for (String s : newlist) {
System.out.println(s);
}
}

作为参考,请参考这个链接如何从数组列表中删除重复项

像这样的东西会更好吗?

public static void removeDuplicates(ArrayList<String> list) {
Arraylist<Object> ar     = new Arraylist<Object>();
Arraylist<Object> tempAR = new Arraylist<Object>();
while (list.size()>0){
ar.add(list(0));
list.removeall(Collections.singleton(list(0)));
}
list.addAll(ar);
}

这应该保持顺序,并且在运行时也不是二次的。

如果你愿意使用第三方库,你可以使用Eclipse集合(以前是GS Collections)中的distinct()方法。

ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());

使用distinct()而不是转换到Set然后再转换回List的优点是,distinct()保留了原始List的顺序,保留了每个元素第一次出现的顺序。它是通过使用Set和List来实现的。

MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;

如果不能将原来的List转换为Eclipse Collections类型,可以使用ListAdapter来获得相同的API。

MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();

我是Eclipse Collections的提交者。

ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");


HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();

假设我们有一个String的列表:

List<String> strList = new ArrayList<>(5);
// insert up to five items to list.

然后我们可以用多种方式删除重复的元素。

Java 8之前

List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));

如果我们想保持插入顺序,那么我们需要使用LinkedHashSet来代替HashSet

使用番石榴

List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));

使用Java 8

List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());

如果我们想在具体的列表实现中收集结果,例如LinkedList,那么我们可以修改上面的例子:

List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));

我们也可以在上面的代码中使用parallelStream,但它可能不会带来预期的性能收益。查看问题了解更多信息。

你也可以这样做,保持秩序:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));

用于自定义对象列表

   public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {


@Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);


final List newList = new ArrayList(set);
return newList;
}

你可以在下面使用嵌套循环:

ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();


Iterator iterator1 = l1.iterator();
boolean repeated = false;


while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}

如果你使用的是模型类型List<T > / ArrayList<T >。希望,它能帮到你。

下面是我的代码,没有使用任何其他数据结构,如set或hashmap

for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}

时间复杂度:O(n):无设置

private static void removeDup(ArrayList<String> listWithDuplicateElements) {
System.out.println(" Original Duplicate List :" + listWithDuplicateElements);
List<String> listWithoutDuplicateElements = new ArrayList<>(listWithDuplicateElements.size());


listWithDuplicateElements.stream().forEach(str -> {
if (listWithoutDuplicateElements.indexOf(str) == -1) {
listWithoutDuplicateElements.add(str);
}
});


System.out.println(" Without Duplicate List :" + listWithoutDuplicateElements);
}

这是正确的(如果您关心HashSet的开销的话)。

 public static ArrayList<String> removeDuplicates (ArrayList<String> arrayList){
if (arrayList.isEmpty()) return null;  //return what makes sense for your app
Collections.sort(arrayList, String.CASE_INSENSITIVE_ORDER);
//remove duplicates
ArrayList <String> arrayList_mod = new ArrayList<>();
arrayList_mod.add(arrayList.get(0));
for (int i=1; i<arrayList.size(); i++){
if (!arrayList.get(i).equals(arrayList.get(i-1))) arrayList_mod.add(arrayList.get(i));
}
return arrayList_mod;
}
Set<String> strSet = strList.stream().collect(Collectors.toSet());

是删除副本的最简单方法。

如果您希望列表自动忽略重复项并保持其顺序,您可以创建HashList(HashMap嵌入式列表)。

public static class HashList<T> extends ArrayList<T>{
private HashMap <T,T> hashMap;
public HashList(){
hashMap=new HashMap<>();
}


@Override
public boolean add(T t){
if(hashMap.get(t)==null){
hashMap.put(t,t);
return super.add(t);
}else return false;
}


@Override
public boolean addAll(Collection<? extends T> c){
HashList<T> addup=(HashList<T>)c;
for(int i=0;i<addup.size();i++){
add(addup.get(i));
}return true;
}


}

# EYZ0

HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);

以下是一个适用于任何对象的解决方案:

public static <T> List<T> clearDuplicates(List<T> messages,Comparator<T> comparator) {
List<T> results = new ArrayList<T>();
for (T m1 : messages) {
boolean found = false;
for (T m2 : results) {
if (comparator.compare(m1,m2)==0) {
found=true;
break;
}
}
if (!found) {
results.add(m1);
}
}
return results;
}

芬兰湾的科特林

val list = listOf('a', 'A', 'b', 'B', 'A', 'a')
println(list.distinct()) // [a, A, b, B]
println(list.distinctBy { it.uppercaseChar() }) // [a, b]

从这里kotlinlang