25 ответов:
метод
addofSetвозвращает логическое значение, если значение уже существует (true, если оно не существует, false, если оно уже существует, см. набор документации).поэтому просто повторите все значения:
public Set<Integer> findDuplicates(List<Integer> listContainingDuplicates) { final Set<Integer> setToReturn = new HashSet(); final Set<Integer> set1 = new HashSet(); for (Integer yourInt : listContainingDuplicates) { if (!set1.add(yourInt)) { setToReturn.add(yourInt); } } return setToReturn; }
Мне тоже нужно было решить эту проблему. Я использовал решение leifg и сделал его универсальным.
private <T> Set<T> findDuplicates(Collection<T> list) { Set<T> duplicates = new LinkedHashSet<T>(); Set<T> uniques = new HashSet<T>(); for(T t : list) { if(!uniques.add(t)) { duplicates.add(t); } } return duplicates; }
Я взял решение Джона Стриклера и переделал его, чтобы использовать API потоков, представленный в JDK8:
private <T> Set<T> findDuplicates(Collection<T> collection) { Set<T> uniques = new HashSet<>(); return collection.stream() .filter(e -> !uniques.add(e)) .collect(Collectors.toSet()); }
int[] nums = new int[] {1, 1, 2, 3, 3, 3}; Arrays.sort(nums); for (int i = 0; i < nums.length-1; i++) { if (nums[i] == nums[i+1]) { System.out.println("duplicate item "+nums[i+1]+" at Location"+(i+1) ); } }очевидно, что вы можете делать с ними все, что хотите (т. е. поместить в набор, чтобы получить уникальный список повторяющихся значений) вместо печати... Это также имеет преимущество записи местоположения дубликатов элементов тоже.
использование Guava на Java 8
private Set<Integer> findDuplicates(List<Integer> input) { // Linked* preserves insertion order so the returned Sets iteration order is somewhat like the original list LinkedHashMultiset<Integer> duplicates = LinkedHashMultiset.create(input); // Remove all entries with a count of 1 duplicates.entrySet().removeIf(entry -> entry.getCount() == 1); return duplicates.elementSet(); }
Это также работает:
public static Set<Integer> findDuplicates(List<Integer> input) { List<Integer> copy = new ArrayList<Integer>(input); for (Integer value : new HashSet<Integer>(input)) { copy.remove(value); } return new HashSet<Integer>(copy); }
вы можете использовать что-то вроде этого:
List<Integer> newList = new ArrayList<Integer>(); for(int i : yourOldList) { yourOldList.remove(i); if(yourOldList.contains(i) && !newList.contains(i)) newList.add(i); }
используйте MultiMap для хранения каждого значения в качестве набора ключей / значений. Затем выполните итерацию по ключам и найдите те, которые имеют несколько значений.
Ламбас может быть решением
Integer[] nums = new Integer[] {1, 1, 2, 3, 3, 3}; List<Integer> list = Arrays.asList(nums); List<Integer> dps = list.stream().distinct().filter(entry -> Collections.frequency(list, entry) > 1).collect(Collectors.toList());
Если вы используете Коллекции Eclipse, это будет работать:
MutableList<Integer> list = Lists.mutable.with(1, 1, 2, 3, 3, 3); Set<Integer> dupes = list.toBag().selectByOccurrences(i -> i > 1).toSet(); Assert.assertEquals(Sets.mutable.with(1, 3), dupes);обновление: начиная с коллекций Eclipse 9.2 теперь вы можете использовать
selectDuplicatesMutableList<Integer> list = Lists.mutable.with(1, 1, 2, 3, 3, 3); Set<Integer> dupes = list.toBag().selectDuplicates().toSet(); Assert.assertEquals(Sets.mutable.with(1, 3), dupes);Примечание: Я коммиттер для коллекций Eclipse.
это проблема, где функциональные методы светит. Например, следующее решение F# является более четким и менее подверженным ошибкам, чем лучшее императивное решение Java (и я ежедневно работаю с Java и F#).
[1;1;2;3;3;3] |> Seq.countBy id |> Seq.choose (fun (key,count) -> if count > 1 then Some(key) else None)конечно, этот вопрос касается Java. Поэтому я предлагаю принять библиотеку, которая приносит функциональные возможности Java. Например, он может быть решен с помощью my библиотека следующим образом (и есть несколько других там стоит глядя На тоже):
Seq.of(1,1,2,3,3,3) .groupBy(new Func1<Integer,Integer>() { public Integer call(Integer key) { return key; } }).filter(new Predicate<Grouping<Integer,Integer>>() { public Boolean call(Grouping<Integer, Integer> grouping) { return grouping.getGrouping().count() > 1; } }).map(new Func1<Grouping<Integer,Integer>,Integer>() { public Integer call(Grouping<Integer, Integer> grouping) { return grouping.getKey(); } });
компактная обобщенная версия верхнего ответа, также добавлена пустая проверка и предварительно выделенный размер набора:
public static final <T> Set<T> findDuplicates(final List<T> listWhichMayHaveDuplicates) { final Set<T> duplicates = new HashSet<>(); final int listSize = listWhichMayHaveDuplicates.size(); if (listSize > 0) { final Set<T> tempSet = new HashSet<>(listSize); for (final T element : listWhichMayHaveDuplicates) { if (!tempSet.add(element)) { duplicates.add(element); } } } return duplicates; }
попробуйте это, чтобы найти дубликаты элементов в списке:
ArrayList<String> arrayList1 = new ArrayList<String>(); arrayList1.add("A"); arrayList1.add("A"); arrayList1.add("B"); arrayList1.add("B"); arrayList1.add("B"); arrayList1.add("C"); for (int x=0; x< arrayList1.size(); x++) { System.out.println("arrayList1 :"+arrayList1.get(x)); } Set s=new TreeSet(); s.addAll(arrayList1); Iterator it=s.iterator(); while (it.hasNext()) { System.out.println("Set :"+(String)it.next()); }
создать
Map<Integer,Integer>, повторите список, если элемент находится на карте, увеличьте его значение, иначе добавьте его на карту с ключом=1
повторите карту и добавьте в списки все элементы с ключом>=2public static void main(String[] args) { List<Integer> list = new LinkedList<Integer>(); list.add(1); list.add(1); list.add(1); list.add(2); list.add(3); list.add(3); Map<Integer,Integer> map = new HashMap<Integer, Integer>(); for (Integer x : list) { Integer val = map.get(x); if (val == null) { map.put(x,1); } else { map.remove(x); map.put(x,val+1); } } List<Integer> result = new LinkedList<Integer>(); for (Entry<Integer, Integer> entry : map.entrySet()) { if (entry.getValue() > 1) { result.add(entry.getKey()); } } for (Integer x : result) { System.out.println(x); } }
Это должно работать для сортированной и несортированной.
public void testFindDuplicates() { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(1); list.add(2); list.add(3); list.add(3); list.add(3); Set<Integer> result = new HashSet<Integer>(); int currentIndex = 0; for (Integer i : list) { if (!result.contains(i) && list.subList(currentIndex + 1, list.size()).contains(i)) { result.add(i); } currentIndex++; } assertEquals(2, result.size()); assertTrue(result.contains(1)); assertTrue(result.contains(3)); }
public class DuplicatesWithOutCollection { public static void main(String[] args) { int[] arr = new int[] { 2, 3, 4, 6, 6, 8, 10, 10, 10, 11, 12, 12 }; boolean flag = false; int k = 1; while (k == 1) { arr = removeDuplicate(arr); flag = checkDuplicate(arr, flag); if (flag) { k = 1; } else { k = 0; } } } private static boolean checkDuplicate(int[] arr, boolean flag) { int i = 0; while (i < arr.length - 1) { if (arr[i] == arr[i + 1]) { flag = true; } else { flag = false; } i++; } return flag; } private static int[] removeDuplicate(int[] arr) { int i = 0, j = 0; int[] temp = new int[arr.length]; while (i < arr.length - 1) { if (arr[i] == arr[i + 1]) { temp[j] = arr[i + 1]; i = i + 2; } else { temp[j] = arr[i]; i = i + 1; if (i == arr.length - 1) { temp[j + 1] = arr[i + 1]; break; } } j++; } System.out.println(); return temp; } }
import java.util.Scanner; public class OnlyDuplicates { public static void main(String[] args) { System.out.print(" Enter a set of 10 numbers: "); int[] numbers = new int[10]; Scanner input = new Scanner(System.in); for (int i = 0; i < numbers.length; i++) { numbers[i] = input.nextInt(); } numbers = onlyDuplicates(numbers); System.out.print(" The numbers are: "); for (int i = 0; i < numbers.length; i++) { System.out.print(numbers[i] + ""); } } public static int[] onlyDuplicates(int[] list) { boolean flag = true; int[] array = new int[0]; array = add2Array(array, list[0]); for (int i = 0; i < list.length; i++) { for (int j = 0; j < array.length; j++) { if (list[i] == array[j]) { flag = false; break; } } if (flag) { array = add2Array(array, list[i]); } flag = true; } return array; } // Copy numbers1 to numbers2 // If the length of numbers2 is less then numbers2, return false public static boolean copyArray(int[] source, int[] dest) { if (source.length > dest.length) { return false; } for (int i = 0; i < source.length; i++) { dest[i] = source[i]; } return true; } // Increase array size by one and add integer to the end of the array public static int[] add2Array(int[] source, int data) { int[] dest = new int[source.length + 1]; copyArray(source, dest); dest[source.length] = data; return dest; } }
public class practicese { public static void main(String[] args) { List<Integer> listOf = new ArrayList<Integer>(); listOf.add(3); listOf.add(1); listOf.add(2); listOf.add(3); listOf.add(3); listOf.add(2); listOf.add(1); List<Integer> tempList = new ArrayList<Integer>(); for(Integer obj:listOf){ if(!tempList.contains(obj)){ tempList.add(obj); } } System.out.println(tempList); } }
Это был бы хороший метод, чтобы найти повторяющиеся значения, не используя Set.
public static <T> List<T> findDuplicates(List<T> list){ List<T> nonDistinctElements = new ArrayList<>(); for(T s : list) if(list.indexOf(s) != list.lastIndexOf(s)) if(!nonDistinctElements.contains(s)) nonDistinctElements.add(s); return nonDistinctElements; }и скажите, что вам нужен метод, который возвращает вам отдельный список, т. е. если вы передадите список, в котором элементы встречаются более одного раза, вы получите список с различными элементами.
public static <T> void distinctList(List<T> list){ List<T> nonDistinctElements = new ArrayList<>(); for(T s : list) if(list.indexOf(s) != list.lastIndexOf(s)) nonDistinctElements.add(s); for(T nonDistinctElement : nonDistinctElements) if(list.indexOf(nonDistinctElement) != list.lastIndexOf(nonDistinctElement)) list.remove(nonDistinctElement); }
и версия, которая использует
commons-collectionsCollectionUtils.getCardinalityMapспособ:final List<Integer> values = Arrays.asList(1, 1, 2, 3, 3, 3); final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(values); System.out.println(cardinalityMap .entrySet() .stream().filter(e -> e.getValue() > 1) .map(e -> e.getKey()) .collect(Collectors.toList()));"'
Как насчет такой код -
public static void main(String[] args) { //Lets say we have a elements in array int[] a = {13,65,13,67,88,65,88,23,65,88,92}; List<Integer> ls1 = new ArrayList<>(); List<Integer> ls2 = new ArrayList<>(); Set<Integer> ls3 = new TreeSet<>(); //Adding each element of the array in the list for(int i=0;i<a.length;i++) { { ls1.add(a[i]); } } //Iterating each element in the arrary for (Integer eachInt : ls1) { //If the list2 contains the iterating element, then add that into set<> (as this would be a duplicate element) if(ls2.contains(eachInt)) { ls3.add(eachInt); } else {ls2.add(eachInt);} } System.out.println("Elements in array or ls1"+ls1); System.out.println("Duplicate Elements in Set ls3"+ls3); }
поместите список в набор (это эффективно фильтрует только уникальные элементы), удалите все элементы набора из исходного списка (так что он будет содержать только элементы, которые имеют более 1 случай) и поместите список в новый набор (это снова отфильтрует только уникальные элементы):
List<Item> list = ...; list.removeAll(new HashSet<Item>(list)); return new HashSet<Item>(list);
Если вы знаете максимальное значение (например
псевдо код:
//does not handle case when mem allocation fails //probably can be extended to unknown values /larger values . maybe by sorting first public List<int> GetDuplicates(int max) { //allocate and clear memory to 0/false bit[] buckets=new bit[max] memcpy(buckets,0,max); //find duplicates List<int> result=new List<int>(); foreach(int val in List) { if (buckets[val]) { result.add(value); } else { buckets[val]=1; } } return result }
просто попробуйте это :
например, если значения списка: [1, 2, 3, 4, 5, 6, 4, 3, 7, 8] повторяющихся элементов [3, 4].
Collections.sort(list); List<Integer> dup = new ArrayList<>(); for (int i = 0; i < list.size() - 1; i++) { if (list.get(i) == list.get(i + 1)) { if (!dup.contains(list.get(i + 1))) { dup.add(list.get(i + 1)); } } } System.out.println("duplicate item " + dup);
java 8 базовое решение:
List duplicates = list.stream().collect(Collectors.groupingBy(Function.identity())) .entrySet() .stream() .filter(e -> e.getValue().size() > 1) .map(Map.Entry::getKey) .collect(Collectors.toList());
Comments