[Java] 如何从ArrayList中删除重复的元素?


Answers

尽管将ArrayList转换为HashSet有效地删除重复项,但如果您需要保留插入顺序,我宁愿建议您使用此变体

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

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

Question

我有一个Strings ArrayList ,我想从中删除重复的字符串。 我怎样才能做到这一点?




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;
        }



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




这是我的答案,没有使用任何其他数据结构,如设置或散列表等。

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;
}






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--;
            }
        }
}



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

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



这可以解决问题:

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;
}



如果你想从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;
}



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

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

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




当你填充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 + " ");     
    }

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




        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]



如果您愿意使用第三方库,则可以在Eclipse集合 (以前称为GS集合)中使用方法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;

如果您无法将原始列表转换为Eclipse集合类型,则可以使用ListAdapter来获取相同的API。

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

注意:我是Eclipse集合的提交者。




假设我们有一个String列表,如下所示:

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

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

在Java 8之前

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

使用番石榴

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

使用Java 8

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

注意:如果我们想维护插入顺序,那么我们需要使用LinkedHashSet来代替HashSet




码:

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);

注意:肯定会有内存开销。






Links