[java] 목록에서 중복 식별

예를 들어 정수 유형의 목록이 있습니다.

[1, 1, 2, 3, 3, 3]

예를 들어 모든 중복을 반환하는 방법을 원합니다.

[1, 3]

이를 수행하는 가장 좋은 방법은 무엇입니까?



답변

의 메서드 addSet값이 이미 존재하는지 여부를 부울 로 반환합니다 (존재하지 않으면 true, 이미 존재하면 false, Set documentation 참조 ).

따라서 모든 값을 반복하십시오.

public Set<Integer> findDuplicates(List<Integer> listContainingDuplicates)
{
  final Set<Integer> setToReturn = new HashSet<>();
  final Set<Integer> set1 = new HashSet<>();

  for (Integer yourInt : listContainingDuplicates)
  {
   if (!set1.add(yourInt))
   {
    setToReturn.add(yourInt);
   }
  }
  return setToReturn;
}


답변

이것에 대한 해결책도 필요했습니다. 나는 leifg의 솔루션을 사용하여 일반화했습니다.

private <T> Set<T> findDuplicates(Collection<T> collection) {

    Set<T> duplicates = new LinkedHashSet<>();
    Set<T> uniques = new HashSet<>();

    for(T t : collection) {
        if(!uniques.add(t)) {
            duplicates.add(t);
        }
    }

    return duplicates;
}


답변

John Strickler의 솔루션을 가져와 JDK8에 도입 된 스트림 API를 사용하도록 다시 만들었습니다.

private <T> Set<T> findDuplicates(Collection<T> collection) {
    Set<T> uniques = new HashSet<>();
    return collection.stream()
        .filter(e -> !uniques.add(e))
        .collect(Collectors.toSet());
}


답변

다음은 Java 8과 함께 Streams를 사용하는 솔루션입니다.

// lets assume the original list is filled with {1,1,2,3,6,3,8,7}
List<String> original = new ArrayList<>();
List<String> result = new ArrayList<>();

이 개체의 빈도가 목록에서 두 번 이상인지 확인합니다. 그런 다음 .distinct ()를 호출하여 결과에 고유 한 요소 만 포함합니다.

result = original.stream()
    .filter(e -> Collections.frequency(original, e) > 1)
    .distinct()
    .collect(Collectors.toList());
// returns {1,3}
// returns only numbers which occur more than once

result = original.stream()
    .filter(e -> Collections.frequency(original, e) == 1)
    .collect(Collectors.toList());
// returns {2,6,8,7}
// returns numbers which occur only once

result = original.stream()
    .distinct()
    .collect(Collectors.toList());
// returns {1,2,3,6,8,7}
// returns the list without duplicates


답변

자바 8 기본 솔루션 :

List duplicates =
list.stream().collect(Collectors.groupingBy(Function.identity()))
    .entrySet()
    .stream()
    .filter(e -> e.getValue().size() > 1)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());


답변

int[] nums =  new int[] {1, 1, 2, 3, 3, 3};
Arrays.sort(nums);
for (int i = 0; i < nums.length-1; i++) {

    if (nums[i] == nums[i+1]) {
        System.out.println("duplicate item "+nums[i+1]+" at Location"+(i+1) );
    }

}

분명히 인쇄하는 대신 원하는 모든 작업을 수행 할 수 있습니다 (즉, 중복 값의 고유 한 목록을 얻기 위해 Set에 넣음). 이것은 또한 중복 항목의 위치를 ​​기록하는 이점도 있습니다.


답변

Java 8에서 Guava 사용

private Set<Integer> findDuplicates(List<Integer> input) {
    // Linked* preserves insertion order so the returned Sets iteration order is somewhat like the original list
    LinkedHashMultiset<Integer> duplicates = LinkedHashMultiset.create(input);

    // Remove all entries with a count of 1
    duplicates.entrySet().removeIf(entry -> entry.getCount() == 1);

    return duplicates.elementSet();
}