How to select duplicate values from a list in java

2019-02-22 18:15发布

For example my list contains {4, 6, 6, 7, 7, 8} and I want final result = {6, 6, 7, 7}

One way is to loop through the list and eliminate unique values (4, 8 in this case).

Is there any other efficient way rather than looping through list ? I asked this question because the list that I am working is very large ? My code is

List<Long> duplicate = new ArrayList();
for (int i = 0; i < list.size(); i++) {
     Long item = (Long) list.get(i);
     if (!duplicate.contains(item)) {
          duplicate.add(item);
         }
     }

10条回答
Juvenile、少年°
2楼-- · 2019-02-22 18:45
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class FindDuplicate {

    public static void main(String[] args) {

        // Load all your ArrayList
        List<String> list = new ArrayList<String>();
        list.add("Jhon");
        list.add("Jency");
        list.add("Mike");
        list.add("Dmitri");
        list.add("Mike");

        // Set will not allow duplicates
        Set<String> checkDuplicates = new HashSet<String>();

        System.out.println("Actual list " + list);
        for (int i = 0; i < list.size(); i++) {
            String items = list.get(i);
            if (!checkDuplicates.add(items)) {
                // retain the item from set interface
                System.out.println("Duplicate in that list " + items);
            }
        }

    }
}
查看更多
姐就是有狂的资本
3楼-- · 2019-02-22 18:45

With Guava and Java 8, it's trivial and fast:

Multiset<Integer> multiset = HashMultiset.create(list);
return list.stream()
    .filter(i -> multiset.count(i) > 1)
    .collect(Collectors.toList());

The first line computes the counts using a sort of a hash map. The remainder is more than obvious.

Something like this could simulate the multiset:

HashMap<Integer, Integer> multiset = new HashMap<>();
list.stream().forEach(i -> 
    multiset.compute(i, (ignored, old) -> old==null ? 1 : old+1)));
查看更多
不美不萌又怎样
4楼-- · 2019-02-22 18:54

I like answer Java 8, Streams to find the duplicate elements. Solution return only unique duplicates.

 Integer[] numbers = new Integer[] { 1, 2, 1, 3, 4, 4 };
 Set<Integer> allItems = new HashSet<>();
 Set<Integer> duplicates = Arrays.stream(numbers)
    .filter(n -> !allItems.add(n)) //Set.add() returns false if the item was already in the set.
    .collect(Collectors.toSet());
 System.out.println(duplicates); // [1, 4]
查看更多
【Aperson】
5楼-- · 2019-02-22 18:57

Given that you can do this by looping through the list only once, I wouldn't worry about performance too much. If you search for more performant solutions then you'll probably end up over-complicating the code and the readability and maintainability will suffer. At the end of the day, if you want to check the whole list for duplicates then you have to visit every element.

I'd advise writing the obvious solution and see how it performs. You'll probably be surprised how fast Java can iterate over a list, even if it is particularly large.

查看更多
叼着烟拽天下
6楼-- · 2019-02-22 18:59

Some good answers so far but another option just for the fun of it. Loop through the list trying to place each number into a Set e.g. a HashSet. If the add method returns false you know the number is a duplicate and should go into the duplicate list.

EDIT: Something like this should do it

Set<Number> unique = new HashSet<>();
List<Number> duplicates = new ArrayList<>();
for( Number n : inputList ) {
    if( !unique.add( n ) ) {
        duplicates.add( n );
    }
}
查看更多
神经病院院长
7楼-- · 2019-02-22 18:59
List<Number> inputList = Arrays.asList(4, 6, 6, 7, 7, 8);
List<Number> result = new ArrayList<Number>();
for(Number num : inputList) {
   if(Collections.frequency(inputList, num) > 1) {
       result.add(num);
   }
}

I am not sure about the efficiency, but I find the code easy to read (and that should be preferred.

EDIT: changing Lists.newArrayList() to new ArrayList<Number>();

查看更多
登录 后发表回答