구현할 수있는 특정 기준에 따라 컬렉션에 중복 항목을 찾을 수있는 도구 또는 라이브러리가 있습니까?컬렉션에서 중복 항목 찾기
분명히하기 : 특정 기준에 따라 서로 항목을 비교하고 싶습니다. 그래서 true
또는 false
만을 반환하는 Predicate
은 충분하지 않다고 생각합니다.
나는 equals
을 사용할 수 없습니다.
구현할 수있는 특정 기준에 따라 컬렉션에 중복 항목을 찾을 수있는 도구 또는 라이브러리가 있습니까?컬렉션에서 중복 항목 찾기
분명히하기 : 특정 기준에 따라 서로 항목을 비교하고 싶습니다. 그래서 true
또는 false
만을 반환하는 Predicate
은 충분하지 않다고 생각합니다.
나는 equals
을 사용할 수 없습니다.
나는 IEqualityComparer<T>
인터페이스와 비슷한 새 인터페이스를 .NET에 만들었습니다.
그런 다음 EqualityComparator<T>
다음은 중복을 감지하는 다음 방법을 전달합니다.
public static <T> boolean hasDuplicates(Collection<T> collection,
EqualsComparator<T> equalsComparator) {
List<T> list = new ArrayList<>(collection);
for (int i = 0; i < list.size(); i++) {
T object1 = list.get(i);
for (int j = (i + 1); j < list.size(); j++) {
T object2 = list.get(j);
if (object1 == object2
|| equalsComparator.equals(object1, object2)) {
return true;
}
}
}
return false;
}
이렇게하면 원하는대로 비교할 수 있습니다.
지도를 사용할 수 있으며 컬렉션을 반복하면서 요소를지도에 넣습니다 (조건부가 키를 형성합니다). 이미 항목이 있으면 중복을 발견했습니다.
자세한 내용은 여기를 참조하십시오 Finding duplicates in a collection
이 기준의 의미에 따라 달라집니다
당신의 기준은 항상 지정된 클래스에 대해 동일한, 그리고에 고유의 경우 기본 개념을 사용하는 경우 equals
및 hashCode
을 구현하고 세트를 사용해야합니다.
은 당신의 기준은 상황에 맞는에 의존하는 경우, org.apache.commons.collections.CollectionUtils.select(java.util.Collection, org.apache.commons.collections.Predicate) 당신을위한 적합한 솔루션이 될 수 있습니다.
임의의 기준이 아닌 서로간에 항목을 비교하고 싶습니다. –
중복을 찾으려면 컬렉션을 배열로 던지고 조건을 구현하는 Comparator를 통해 배열을 정렬 한 다음 배열을 선형 적으로 살펴보고 인접한 중복에 대해서.
여기 (안 테스트) 스케치입니다 :
MyComparator myComparator = new MyComparator();
MyType[] myArray = myList.toArray();
Arrays.sort(myArray, myComparator);
for (int i = 1; i < myArray.length; ++i) {
if (0 == myComparator.compare(myArray[i - 1], myArray[i])) {
// Found a duplicate!
}
}
편집 : 귀하의 코멘트에서, 당신은 단지 이 중복이 있는지 알고 싶습니다. 위의 접근 방식도 이와 관련됩니다. 그러나 사용자 정의 Comparator를 사용하여 java.util.SortedSet을 생성하면됩니다. 여기 스케치는 다음과 같습니다
MyComparator myComparator = new MyComparator();
TreeSet treeSet = new TreeSet(myComparator);
treeSet.addAll(myCollection);
boolean containsDuplicates = (treeSet.size() != myCollection.size());
당신은 임의의 유형의 객체 간의 중복을 검색 할 자바 설정을 적용 할 수 있습니다 : 당신의 기준에 따라 평등을 평가하는 개인 래퍼에서 대상 클래스를 포장하고 래퍼의 세트를 구성 .
다음은이 기술을 설명하는 다소 긴 예제입니다. 동일한 이름을 가진 두 사람이 같다고 생각하기 때문에 5 개의 객체 배열에서 3 개의 중복을 감지합니다.
import java.util.*;
import java.lang.*;
class Main {
static class Person {
private String first;
private String last;
public String getFirst() {return first;}
public String getLast() {return last;}
public Person(String f, String l) {
first = f;
last = l;
}
public String toString() {
return first+" "+last;
}
}
public static void main (String[] args) throws java.lang.Exception {
List<Person> people = new ArrayList<Person>();
people.add(new Person("John", "Smith"));
people.add(new Person("John", "Scott"));
people.add(new Person("Jack", "First"));
people.add(new Person("John", "Walker"));
people.add(new Person("Jack", "Black"));
Set<Object> seen = new HashSet<Object>();
for (Person p : people) {
final Person thisPerson = p;
class Wrap {
public int hashCode() { return thisPerson.getFirst().hashCode(); }
public boolean equals(Object o) {
Wrap other = (Wrap)o;
return other.wrapped().getFirst().equals(thisPerson.getFirst());
}
public Person wrapped() { return thisPerson; }
};
Wrap wrap = new Wrap();
if (seen.add(wrap)) {
System.out.println(p + " is new");
} else {
System.out.println(p + " is a duplicate");
}
}
}
}
이 예제는 ideone [link]에서 재생할 수 있습니다.
+1 : 흥미 롭습니다! 효율성을 전혀 모릅니다. – dragon66
@ dragon66 해쉬 함수가 좋은 경우 효율성은 모든 항목의 'O (1)'또는 전체 모음의 'O (N)'인 해시 테이블과 동일합니다. – dasblinkenlight
dasblinkenlight : 루프 외부로 나가는 것을 알고 있지만 랩 오브젝트 생성에 대해 조금 걱정됩니다. – dragon66
중복 된 내용이 포함 된 ArrayList
을 반복하고 HashSet
에 추가하십시오. HashSet
에서 add 메소드가 false를 반환하면 콘솔에 복제본을 기록하십시오.
OP가 말하기를, 그는 equals()를 사용할 수 없습니다. 'HashSet'은'hashCode()'와'equals()'를 사용합니다. 따라서 그는'HashSet'을 사용할 수 없습니다. –
TreeSet의 쉽게이 작업을 수행 할 수 있습니다 : 세트에 항목을 추가하고 항목이 고유 한 경우 true
를 반환 uniqueItems.add(o)
를 호출 할 때
Set uniqueItems = new TreeSet<>(yourComparator);
List<?> duplicates = objects.stream().filter(o -> !uniqueItems.add(o)).collect(Collectors.toList());
yourComarator
사용됩니다. 비교자가 항목을 중복으로 간주하면 add(o)
은 false를 반환합니다.
이 항목의 equals
메서드는 the TreeSet documentation에 따라 yourComarator
과 일치해야합니다.
어떤 방식으로 중복 제거 기준을 지정 하시겠습니까? 이진 술어로서? – NPE
중복을 찾거나 * 제거 * 하시겠습니까? –
@ AndyThomas-Cramer 실제로 복제본이 있는지를 아는 것만으로도 충분합니다. –