如何从ArrayList中删除重复的元素?
我有一个Strings
ArrayList
,我想从中删除重复的string。 我该怎么做?
如果你不想在一个Collection
重复,你应该考虑为什么你使用允许重复的Collection
。 删除重复元素的最简单方法是将内容添加到Set
(不允许重复),然后将Set
添加回ArrayList
:
List<String> al = new ArrayList<>(); // add elements to al, including duplicates Set<String> hs = new HashSet<>(); hs.addAll(al); al.clear(); al.addAll(hs);
当然,这破坏了ArrayList
元素的sorting。
尽pipe将ArrayList
转换为HashSet
有效地删除重复项,但如果需要保留插入顺序,我宁愿build议您使用此变体
// list is some List of Strings Set<String> s = new LinkedHashSet<>(list);
然后,如果您需要取回List
引用,则可以再次使用转换构造函数。
在Java 8中:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
请注意,应该遵守列表成员的hashCode-equals约定,以使筛选正常工作。
如果你不想重复,使用Set而不是List
。 要将List
转换为Set
,可以使用以下代码:
// list is some List of Strings Set<String> s = new HashSet<String>(list);
如果真的有必要,可以使用相同的构造将Set
转换回List
。
这是一个不影响你的列表sorting的方法:
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根据你想要expression的等同性来确定equals方法)
还有Guava的 ImmutableSet
作为选项( 这里是文档):
ImmutableSet.copyOf(list);
Java 8stream提供了一个非常简单的方法来从列表中删除重复的元素。 使用不同的方法。 如果我们有一个城市的列表,我们想删除该列表中的重复项,可以在一行中完成 –
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删除重复,而不使用HashSet或多一个ArrayList 。
试试这个代码
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]
假设我们有一个String
列表,如下所示:
List<String> strList = new ArrayList<>(5); // insert up to five items to list.
然后我们可以通过多种方式删除重复的元素。
在Java 8之前
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
使用番石榴
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
使用Java 8
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
注意:如果我们想维护插入顺序,那么我们需要使用LinkedHashSet
代替HashSet
。
大概有点矫枉过正,但我喜欢这种孤立的问题。 🙂
此代码使用临时Set(用于唯一性检查),但直接删除原始列表中的元素。 由于ArrayList中的元素移除会导致大量的数组复制,因此可以避免使用remove(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(); } } }
使用标记界面为列表提供统一的解决scheme:
public static <T> void removeDuplicates(List<T> list) { if (list instanceof RandomAccess) { // use first version here } else { // use other version here } }
编辑:我猜generics东西并不真的在这里增加任何价值..哦,哦。 🙂
这可以解决这个问题:
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; }
你也可以这样做,并保持秩序:
// delete duplicates (if any) from 'myArrayList' myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
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); }
如果您愿意使用第三方库,则可以在Eclipse集合 (以前称为GS集合)中使用方法distinct()
)。
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1); Assert.assertEquals( FastList.newListWith(1, 3, 2), integers.distinct());
使用distinct()
而不是转换为Set然后返回List的优点是distinct()
保留了原始List的顺序,保留了每个元素的第一次出现。 它通过使用Set和List来实现。
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 Collectionstypes,则可以使用ListAdapter来获取相同的API。
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
注意:我是Eclipse集合的提交者。
这三行代码可以从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();
如前所述,您应该使用实现Set接口而不是List的类来确保元素的唯一性。 如果必须保持元素的顺序,则可以使用SortedSet接口; TreeSet类实现该接口。
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]
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的重复意味着find下面的逻辑,
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; }
@ jonathan-stafford解决scheme是可以的。 但是这不保留列表顺序。
如果你想保留列表顺序,你必须使用这个:
public static <T> void removeDuplicate(List <T> list) { Set <T> set = new HashSet <T>(); List <T> newList = new ArrayList <T>(); for (Iterator <T>iter = list.iterator(); iter.hasNext(); ) { Object element = iter.next(); if (set.add((T) element)) newList.add((T) element); } list.clear(); list.addAll(newList); }
只是要完成答案。 很好!
这是我的答案,没有使用任何其他数据结构,如设置或散列表等
public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) { ArrayList <T> uniqueArrayList = new ArrayList<T>(); for (int i = 0; i < myList.size(); i++){ if (!uniqueArrayList.contains(myList.get(i))){ uniqueArrayList.add(myList.get(i)); } } return uniqueArrayList; }
像这样的工作会更好吗?
public static void removeDuplicates(ArrayList<String> list) { Arraylist<Object> ar = new Arraylist<Object>(); Arraylist<Object> tempAR = new Arraylist<Object>(); while (list.size()>0){ ar.add(list(0)); list.removeall(Collections.singleton(list(0))); } list.addAll(ar);
}
这应该保持顺序,也不是运行时间的二次方。