ฉันมีArrayList<String>
และฉันต้องการที่จะลบสายซ้ำจากมัน ฉันจะทำสิ่งนี้ได้อย่างไร
ฉันมีArrayList<String>
และฉันต้องการที่จะลบสายซ้ำจากมัน ฉันจะทำสิ่งนี้ได้อย่างไร
คำตอบ:
หากคุณไม่ต้องการให้ข้อมูลซ้ำใน a Collection
คุณควรพิจารณาว่าทำไมคุณถึงใช้งานCollection
ซ้ำ วิธีที่ง่ายที่สุดในการลบองค์ประกอบที่ทำซ้ำคือการเพิ่มเนื้อหาลงในSet
(ซึ่งจะไม่อนุญาตให้ทำซ้ำ) และเพิ่มSet
กลับไปที่ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
ArrayList
ของหลักสูตรนี้ทำลายการสั่งซื้อขององค์ประกอบในที่
public Set<Object> findDuplicates(List<Object> list) { Set<Object> items = new HashSet<Object>(); Set<Object> duplicates = new HashSet<Object>(); for (Object item : list) { if (items.contains(item)) { duplicates.add(item); } else { items.add(item); } } return duplicates; }
List
และSet
(แทนที่จะเป็นประเภทการนำไปปฏิบัติArrayList
และHashSet
เป็นตัวอย่างของคุณ)
new HashSet(al)
addAll
Object
มีหลายค่าหากสองค่าของฉันซ้ำฉันถือว่าพวกเขาซ้ำกัน (ค่าอื่นสามารถแตกต่างกัน) และใช้Set
?
แม้ว่าการแปลงArrayList
ไปเป็นการHashSet
ลบที่ซ้ำกันได้อย่างมีประสิทธิภาพหากคุณต้องการรักษาลำดับการแทรกฉันควรแนะนำให้คุณใช้ตัวแปรนี้
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
จากนั้นหากคุณต้องการรับList
ข้อมูลอ้างอิงกลับคุณสามารถใช้เครื่องมือสร้าง Conversion อีกครั้งได้
ใน Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
โปรดทราบว่าสัญญาhashCode- เท่ากับสมาชิกรายการควรได้รับการเคารพเพื่อให้ตัวกรองทำงานได้อย่างถูกต้อง
addAll
new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)
องค์ประกอบแรกที่เพิ่มจะยังคงอยู่ในชุดดังนั้นหากรายการของคุณมี "Dog" และ "dog" (ตามลำดับ) TreeSet
จะมี "Dog" list.replaceAll(String::toUpperCase);
หากคำสั่งซื้อจะต้องได้รับการเก็บรักษาไว้แล้วก่อนที่จะสายในใส่คำตอบ
สมมติว่าเรามีรายการสิ่งที่String
ชอบ:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
จากนั้นเราสามารถลบองค์ประกอบที่ซ้ำกันได้หลายวิธี
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
หมายเหตุ:หากเราต้องการรักษาลำดับการแทรกเราจำเป็นต้องใช้LinkedHashSet
แทนHashSet
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
หมายเหตุ: ในกรณีที่เราต้องการรวบรวมผลลัพธ์ในการใช้งานรายการเฉพาะเช่นLinkedList
จากนั้นเราสามารถแก้ไขตัวอย่างข้างต้นเป็น:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
เราสามารถใช้parallelStream
ในรหัสข้างต้น แต่มันอาจไม่ให้ประโยชน์ performace ที่คาดไว้ ตรวจสอบคำถามนี้เพิ่มเติม
parallel streams
จะให้ประสิทธิภาพที่ดีขึ้นเสมอ แต่มันก็เป็นตำนาน ฉันภายหลังทราบว่ามีบางสถานการณ์ที่ควรใช้สตรีมขนาน ในสถานการณ์นี้สตรีมแบบขนานจะไม่ให้ประสิทธิภาพที่ดีขึ้น และใช่สตรีมแบบขนานอาจไม่ให้ผลลัพธ์ที่ต้องการในบางกรณี List<String> deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
ควรเป็นคำตอบที่เหมาะสมในกรณีนี้
หากคุณไม่ต้องการที่ซ้ำกันใช้ชุดList
แทน ในการแปลง a เป็นList
a Set
คุณสามารถใช้รหัสต่อไปนี้:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
หากจำเป็นจริงๆคุณสามารถใช้การก่อสร้างเดียวกันเพื่อแปลงกลับเข้ามาSet
List
Set
ไม่สามารถใช้ที่นี่
คุณสามารถทำได้ด้วยวิธีนี้และรักษาลำดับไว้:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
สตรีม Java 8 มอบวิธีที่ง่ายมากในการลบองค์ประกอบที่ซ้ำกันออกจากรายการ ใช้วิธีการที่แตกต่าง หากเรามีรายชื่อเมืองและเราต้องการลบรายการที่ซ้ำออกจากรายการนั้นสามารถทำได้ในบรรทัดเดียว -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
นี่คือวิธีที่จะไม่ส่งผลกระทบต่อการสั่งซื้อรายการของคุณ:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 เป็นรายการดั้งเดิมและ l2 เป็นรายการที่ไม่มีรายการซ้ำ (ตรวจสอบให้แน่ใจว่า YourClass มีวิธีการเท่ากับตามสิ่งที่คุณต้องการให้เท่าเทียมกัน)
ArrayList<T>
ควรจะนำมาใช้แทนArrayList
) 2) การสร้าง iterator for (T current : l1) { ... }
อย่างชัดเจนสามารถหลีกเลี่ยงได้โดยใช้ แม้ว่าคุณต้องการใช้Iterator
อย่างชัดเจน แต่iterador
ก็สะกดผิด
มันเป็นไปได้ที่จะลบรายการที่ซ้ำกันออกจากรายการอาร์เรย์โดยไม่ต้องใช้HashSetหรืออีกหนึ่งรายการรายการ
ลองรหัสนี้ ..
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
ผลผลิตคือ
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
ImmutableSet.copyOf(lst).toList()
เปรียบเทียบกับ
indexOf
ซ้ำการlst
ใช้ for for loop
นอกจากนี้ยังมีImmutableSet
จากGuavaเป็นตัวเลือก ( นี่คือเอกสารประกอบ):
ImmutableSet.copyOf(list);
ImmutableSet.asList()
วิธีการส่งคืนถ้าคุณต้องการมันกลับมาเป็นImmutableList
List
สิ่งนี้สามารถแก้ปัญหาได้:
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
อาจจะ overkill เล็กน้อย แต่ฉันสนุกกับปัญหาที่แยกนี้ :)
รหัสนี้ใช้ชุดชั่วคราว (สำหรับการตรวจสอบความเป็นเอกลักษณ์) แต่จะลบองค์ประกอบภายในรายการเดิมโดยตรง เนื่องจากการลบองค์ประกอบภายใน ArrayList สามารถทำให้เกิดการคัดลอกอาเรย์จำนวนมากได้ดังนั้นการหลีกเลี่ยงการลบ (int) - วิธีการ
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
ในขณะที่เราอยู่ที่นี่นี่เป็นเวอร์ชั่นสำหรับ LinkedList (มากขึ้น!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
ใช้อินเทอร์เฟซของตัวทำเครื่องหมายเพื่อนำเสนอโซลูชันแบบรวมสำหรับรายการ:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
แก้ไข: ฉันเดาว่ายาชื่อสามัญไม่ได้เพิ่มคุณค่าใด ๆ ที่นี่จริงๆ :)
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
หากคุณยินดีที่จะใช้ห้องสมุดบุคคลที่สามคุณสามารถใช้วิธีนี้distinct()
ในEclipse Collections (ชื่อเดิมคือ GS Collections)
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
ข้อดีของการใช้distinct()
แทนการแปลงเป็น Set จากนั้นกลับสู่รายการคือdistinct()
รักษาลำดับของรายการดั้งเดิมโดยคงการเกิดขึ้นครั้งแรกของแต่ละองค์ประกอบไว้ มันนำมาใช้โดยใช้ทั้งชุดและรายการ
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
หากคุณไม่สามารถแปลง List ดั้งเดิมของคุณเป็นประเภท Eclipse Collections คุณสามารถใช้ ListAdapter เพื่อรับ API เดียวกัน
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
หมายเหตุ:ฉันเป็นคอมมิชชันสำหรับ Eclipse Collections
รหัสสามบรรทัดนี้สามารถลบองค์ประกอบที่ซ้ำกันออกจาก ArrayList หรือการรวบรวมใด ๆ
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
เมื่อคุณกรอก ArrayList ให้ใช้เงื่อนไขสำหรับแต่ละองค์ประกอบ ตัวอย่างเช่น:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
เราจะได้อาเรย์ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
หากคุณต้องการที่จะรักษาคำสั่งซื้อของคุณก็จะดีที่สุดคือใช้LinkedHashSet เนื่องจากถ้าคุณต้องการส่งรายการนี้ไปยังคิวรีแทรกโดยการวนซ้ำคำสั่งซื้อจะถูกเก็บไว้
ลองสิ่งนี้
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
การแปลงนี้จะมีประโยชน์มากเมื่อคุณต้องการส่งคืนรายการ แต่ไม่ใช่ชุด
รหัส:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
หมายเหตุ:แน่นอนจะมีค่าใช้จ่ายหน่วยความจำ
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
LinkedHashSet จะทำเคล็ดลับ
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
// ผลลัพธ์: 5,1,2,3,4
List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
ใช้สำหรับรายการ Custom Objects ของคุณ
public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}
คุณสามารถใช้การวนซ้ำซ้อนกันในการติดตาม:
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}
ดังที่ได้กล่าวไว้ก่อนหน้านี้คุณควรใช้คลาสที่ใช้อินเทอร์เฟซการตั้งค่าแทนรายการเพื่อให้แน่ใจถึงความเป็นอันหนึ่งอันเดียวกันขององค์ประกอบ หากคุณต้องรักษาลำดับขององค์ประกอบคุณสามารถใช้อินเทอร์เฟซ SortedSet ได้ คลาส TreeSet ใช้อินเตอร์เฟสนั้น
นี่คือรหัสของฉันโดยไม่ใช้โครงสร้างข้อมูลอื่น ๆ เช่น set หรือ hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}
for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}
import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}
public Set<Object> findDuplicates(List<Object> list) {
Set<Object> items = new HashSet<Object>();
Set<Object> duplicates = new HashSet<Object>();
for (Object item : list) {
if (items.contains(item)) {
duplicates.add(item);
} else {
items.add(item);
}
}
return duplicates;
}
ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);
หากคุณต้องการลบรายการที่ซ้ำกันออกจาก ArrayList หมายถึงค้นหาตรรกะด้านล่าง
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}