2 개의 사용자 정의 객체의 ArrayList가 있습니다. 두 ArrayList에서 중복 항목을 제거하고 싶습니다.Java ArrayList 두 목록에서 중복을 제거합니다.
개체에는 fName, lName 및 id라는 세 개의 필드가 있습니다. id가 여러 번 발생하면 두 목록에서 모두 제거하려고합니다.
어떻게하면됩니까?
두 목록을 병합하고 2 개의 중복 항목을 제거하는 것이 좋습니다.
2 개의 사용자 정의 객체의 ArrayList가 있습니다. 두 ArrayList에서 중복 항목을 제거하고 싶습니다.Java ArrayList 두 목록에서 중복을 제거합니다.
개체에는 fName, lName 및 id라는 세 개의 필드가 있습니다. id가 여러 번 발생하면 두 목록에서 모두 제거하려고합니다.
어떻게하면됩니까?
두 목록을 병합하고 2 개의 중복 항목을 제거하는 것이 좋습니다.
병합하려면 : 두 목록의 내용을지도에 간단히 복사하십시오. 그럼 당신은 더 이상 중복이없는 (그러나 당신은 당신의 실제 순서를 느슨하게) :
Map<Integer, MyObject> temp = new HashMap<Integer, MyObject>();
for (MyObject obj:firstList) {
temp.put(obj.getId(), obj);
}
for (MyObject obj:secondList) {
temp.put(obj.getId(), obj);
}
List<MyObject> result = new ArrayList<MyObject>(temp.values());
을 수업이 equals
및 hashCode
방법의 올바른 구현이있는 경우, 중복을 제거하기 위해 HashSet
으로 목록을 켭니다. HashSet<T>
생성자는 Collection<T>
을 허용하므로 잘 보내야합니다.
사용자 지정 비교 함수 (예 : id
만 비교)가 필요한 경우 TreeSet
을 만들 때 사용자 지정 Comparator<T>
구현을 전달하십시오. 요약하면 두 개체의 id
을 비교하는 비교기를 만들고이를 TreeSet
생성자로 전달합니다. 그런 다음 두 목록의 항목을이 집합에 추가하면 중복을 제거 할 수 있습니다. 다음과 같이하십시오 :
public class Test {
public static void main(String[] args) {
Person p1 = new Person("first", "id1");
Person p2 = new Person("dummy", "id1"); // same id as above
Person p3 = new Person("second", "id2");
Person p4 = new Person("third", "id1");
List<Person> asList = Arrays.asList(p1, p2, p3, p4);
CustomComparator comparator = new CustomComparator();
TreeSet<Person> ts = new TreeSet<Person>(comparator);
TreeSet<Person> duplicates = new TreeSet<Person>(comparator);
for (Person p : asList) {
if (ts.contains(p) || duplicates.contains(p)) {
duplicates.add(p);
ts.remove(p);
} else {
ts.add(p);
}
}
System.out.println(ts);
}
}
class Person {
public Person(String name, String id) {
super();
this.name = name;
this.id = id;
}
public String name;
public String id;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Person [id=");
builder.append(id);
builder.append(", name=");
builder.append(name);
builder.append("]");
return builder.toString();
}
}
class CustomComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.id.compareTo(o2.id);
}
}
사실 나는 이미 필드 fName ..에 따라 중복 제거 equals()를 재정의하고 있습니다 (즉, removeAll을 사용하여 목록 중 하나에서 공용 fName을 제거하십시오) ... 그러나 "id"필드의 경우 두 목록에서 모두 제거하고 싶습니다. 내가 어떻게 이것을 습득 할 수 있는지 확실하지 않니? – testndtv
설명을 위해 샘플 스 니펫을 추가했습니다. –
방금 전 예를 들어 보았습니다 ... 복제 된 개체 중 하나가 제거되었습니다 ... 중복 된 개체를 모두 제거하고 싶습니다. 귀하의 예제에 따라, 결국, 그것은 단지 하나의 레코드 (ID2)를 반환해야합니다 ... – testndtv
Set을 사용하십시오.
참고 : 변경 가능한 개체가 설정된 요소로 사용되는 경우 큰주의가 필요합니다. 오브젝트가 세트의 요소 인 동안 equals 비교에 영향을주는 방식으로 오브젝트의 값이 변경되면 세트의 작동은 지정되지 않습니다. 이 금지의 특별한 경우는 세트가 자신을 요소로 포함하는 것이 허용되지 않는다는 것입니다.
HashSet<Integer> list_1_ids = new HashSet<Integer>();
HashSet<Integer> list_2_ids = new HashSet<Integer>();
for (CustomObject x : list1) list_1_ids.add(x.id);
for (CustomObject x : list2) list_2_ids.add(x.id);
HashSet<Integer> both_ids = list_1_ids;
both_ids.retainAll(list_2_ids);
List<CustomObject> pruned_list_1 = new ArrayList<CustomObject>();
for (CustomObject x : list1) if (!both_ids.contains(x.id)) pruned_list_1.add(x);
List<CustomObject> pruned_list_2 = new ArrayList<CustomObject>();
for (CustomObject x : list2) if (!both_ids.contains(x.id)) pruned_list_2.add(x);
그는 결합 목록을 단 하나가 아니라 두 목록에서 중복을 제거하려고합니다. –
병합은 괜찮 았지만주의를 기울이지 않았습니다. 객체는 동일한 ID 만 갖고 있으면 "중복"됩니다. 그래서지도 더 나은 접근입니다 –
고마워요 안드레아스, 그 작동 중대한 .... – John