ฉันมีสองArrayList
วัตถุที่มีจำนวนเต็มสามตัว ฉันต้องการหาวิธีคืนค่าองค์ประกอบทั่วไปของทั้งสองรายการ มีใครคิดว่าฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
ฉันมีสองArrayList
วัตถุที่มีจำนวนเต็มสามตัว ฉันต้องการหาวิธีคืนค่าองค์ประกอบทั่วไปของทั้งสองรายการ มีใครคิดว่าฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
คำตอบ:
listA.retainAll(listB);
// listA now contains only the elements which are also contained in listB.
หากคุณต้องการหลีกเลี่ยงไม่ให้การเปลี่ยนแปลงได้รับผลกระทบlistA
คุณต้องสร้างการเปลี่ยนแปลงใหม่
List<Integer> common = new ArrayList<Integer>(listA);
common.retainAll(listB);
// common now contains only the elements which are contained in listA and listB.
Collection#retainAll()
และความคิดเห็นในส่วนย่อยของโค้ดไม่มันไม่ได้ การเปลี่ยนแปลงจะแสดงในรายการที่คุณกำลังเรียกใช้เมธอด
คุณสามารถใช้การดำเนินการจุดตัดกับArrayList
วัตถุของคุณ
สิ่งนี้:
List<Integer> l1 = new ArrayList<Integer>();
l1.add(1);
l1.add(2);
l1.add(3);
List<Integer> l2= new ArrayList<Integer>();
l2.add(4);
l2.add(2);
l2.add(3);
System.out.println("l1 == "+l1);
System.out.println("l2 == "+l2);
List<Integer> l3 = new ArrayList<Integer>(l2);
l3.retainAll(l1);
System.out.println("l3 == "+l3);
ตอนนี้l3
ควรจะมีเพียงองค์ประกอบร่วมกันระหว่างและl1
l2
CONSOLE OUTPUT
l1 == [1, 2, 3]
l2 == [4, 2, 3]
l3 == [2, 3]
l2
เช่นกัน คุณอาจหมายถึงพูดList<Integer> l3 = new ArrayList<Integer>(l2);
แทน
ทำไมต้องคิดค้นล้อใหม่? ใช้Commons Collections :
CollectionUtils.intersection(java.util.Collection a, java.util.Collection b)
retainAll()
องค์ประกอบซ้ำ ๆ มีแนวโน้มว่าจะถูกต้องและอย่างใดอย่างหนึ่งไม่ถูกต้องขึ้นอยู่กับวิธีที่คุณแก้ไขปัญหา
ใช้Stream.filter()
วิธีการของ Java 8 ร่วมกับList.contains()
:
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
/* ... */
List<Integer> list1 = asList(1, 2, 3, 4, 5);
List<Integer> list2 = asList(1, 3, 5, 7, 9);
List<Integer> common = list1.stream().filter(list2::contains).collect(toList());
List<String> lista =new ArrayList<String>();
List<String> listb =new ArrayList<String>();
lista.add("Isabella");
lista.add("Angelina");
lista.add("Pille");
lista.add("Hazem");
listb.add("Isabella");
listb.add("Angelina");
listb.add("Bianca");
// Create an aplusb list which will contain both list (list1 and list2) in which common element will occur twice
List<String> listapluslistb =new ArrayList<String>(lista);
listapluslistb.addAll(listb);
// Create an aunionb set which will contain both list (list1 and list2) in which common element will occur once
Set<String> listaunionlistb =new HashSet<String>(lista);
listaunionlistb.addAll(listb);
for(String s:listaunionlistb)
{
listapluslistb.remove(s);
}
System.out.println(listapluslistb);
List<Integer> listA = new ArrayList<>();
listA.add(1);
listA.add(5);
listA.add(3);
listA.add(4);
List<Integer> listB = new ArrayList<>();
listB.add(1);
listB.add(5);
listB.add(6);
listB.add(7);
System.out.println(listA.stream().filter(listB::contains).collect(Collectors.toList()));
Java 1.8 Stream API Solutions
เอาต์พุต [1, 5]
คุณสามารถรับองค์ประกอบทั่วไประหว่างสองรายการโดยใช้เมธอด "RetainAll" วิธีนี้จะลบองค์ประกอบที่ไม่ตรงกันทั้งหมดออกจากรายการที่ใช้
Ex.: list.retainAll(list1);
ในกรณีนี้จากรายการองค์ประกอบทั้งหมดที่ไม่อยู่ใน list1 จะถูกลบออกและจะเหลือเพียงองค์ประกอบซึ่งเป็นเรื่องธรรมดาระหว่าง list และ list1
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(13);
list.add(12);
list.add(11);
List<Integer> list1 = new ArrayList<>();
list1.add(10);
list1.add(113);
list1.add(112);
list1.add(111);
//before retainAll
System.out.println(list);
System.out.println(list1);
//applying retainAll on list
list.retainAll(list1);
//After retainAll
System.out.println("list::"+list);
System.out.println("list1::"+list1);
เอาท์พุต:
[10, 13, 12, 11]
[10, 113, 112, 111]
list::[10]
list1::[10, 113, 112, 111]
หมายเหตุ: หลังจากใช้งาน RetainAll ในรายการรายการจะมีองค์ประกอบทั่วไประหว่างรายการและรายการ 1
public <T> List<T> getIntersectOfCollections(Collection<T> first, Collection<T> second) {
return first.stream()
.filter(second::contains)
.collect(Collectors.toList());
}
พิจารณาสองรายการ L1 ans L2
การใช้ Java8 เราสามารถค้นหาได้อย่างง่ายดาย
L1.stream().filter(L2::contains).collect(Collectors.toList())
// Create two collections:
LinkedList<String> listA = new LinkedList<String>();
ArrayList<String> listB = new ArrayList<String>();
// Add some elements to listA:
listA.add("A");
listA.add("B");
listA.add("C");
listA.add("D");
// Add some elements to listB:
listB.add("A");
listB.add("B");
listB.add("C");
// use
List<String> common = new ArrayList<String>(listA);
// use common.retainAll
common.retainAll(listB);
System.out.println("The common collection is : " + common);
ในกรณีที่อยากทำเอง ..
List<Integer> commons = new ArrayList<Integer>();
for (Integer igr : group1) {
if (group2.contains(igr)) {
commons.add(igr);
}
}
System.out.println("Common elements are :: -");
for (Integer igr : commons) {
System.out.println(" "+igr);
}
commons
ประกอบด้วยองค์ประกอบทั่วไป สำหรับลูปที่สองจะพิมพ์บนคอนโซล ฉันไม่เห็นว่าโค้ดกำลังนับองค์ประกอบทั่วไปอยู่ที่ใด
คำตอบด้านบนบางคำตอบคล้ายกัน แต่ไม่เหมือนกันดังนั้นจึงโพสต์เป็นคำตอบใหม่
วิธีแก้ไข:
1. ใช้ HashSet เพื่อเก็บองค์ประกอบที่จำเป็นต้องลบออก
2. เพิ่มองค์ประกอบทั้งหมดของ list1 ไปที่ HashSet
3. วนซ้ำ list2 และลบองค์ประกอบออกจาก HashSet ซึ่งมีอยู่ใน list2 ==> ซึ่งมีอยู่ทั้ง list1 และ list2
4 ตอนนี้ทำซ้ำบน HashSet และลบองค์ประกอบออกจาก list1 (เนื่องจากเราได้เพิ่มองค์ประกอบทั้งหมดของ list1 เพื่อตั้งค่า) ในที่สุด list1 ก็มีองค์ประกอบทั่วไปทั้งหมด
หมายเหตุ: เราสามารถเพิ่มองค์ประกอบทั้งหมดของ list2 และในการทำซ้ำครั้งที่ 3 เราควรลบองค์ประกอบออกจาก รายการ 2.
ความซับซ้อนของเวลา: O (n)
ความซับซ้อนของพื้นที่: O (n)
รหัส:
import com.sun.tools.javac.util.Assert;
import org.apache.commons.collections4.CollectionUtils;
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
List<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(3);
list2.add(5);
list2.add(7);
Set<Integer> toBeRemoveFromList1 = new HashSet<>(list1);
System.out.println("list1:" + list1);
System.out.println("list2:" + list2);
for (Integer n : list2) {
if (toBeRemoveFromList1.contains(n)) {
toBeRemoveFromList1.remove(n);
}
}
System.out.println("toBeRemoveFromList1:" + toBeRemoveFromList1);
for (Integer n : toBeRemoveFromList1) {
list1.remove(n);
}
System.out.println("list1:" + list1);
System.out.println("collectionUtils:" + CollectionUtils.intersection(list1, list2));
Assert.check(CollectionUtils.intersection(list1, list2).containsAll(list1));
เอาท์พุท:
list1:[1, 2, 3, 4, 5]
list2:[1, 3, 5, 7]
toBeRemoveFromList1:[2, 4]
list1:[1, 3, 5]
collectionUtils:[1, 3, 5]
ด้านล่างรหัสลบองค์ประกอบทั่วไปในรายการ
List<String> result = list1.stream().filter(item-> !list2.contains(item)).collect(Collectors.toList());
ดึงองค์ประกอบทั่วไป
List<String> result = list1.stream()
.distinct()
.filter(list::contains)
.collect(Collectors.toList());
public static <T> List<T> getCommonElements(
java.util.Collection<T> a,
java.util.Collection<T> b
) {
if(a==null && b==null) return new ArrayList<>();
if(a!=null && a.size()==0) return new ArrayList<>(b);
if(b!=null && b.size()==0) return new ArrayList<>(a);
Set<T> set= a instanceof HashSet?(HashSet<T>)a:new HashSet<>(a);
return b.stream().filter(set::contains).collect(Collectors.toList());
}
เพื่อประสิทธิภาพเวลาที่ดีขึ้นโปรดใช้ HashSet (O (1) look up) แทน List (O (n) look ups)
ความซับซ้อนของเวลา - O (b) ความซับซ้อนของพื้นที่ - O (a)