问答中心分类: JAVA如何从 ArrayList 中删除重复的元素?
0
匿名用户 提问 3分钟 前

我有一个ArrayList,我想从中删除重复的字符串。我怎样才能做到这一点?

29 Answers
0
abahgat 回答 3分钟 前

虽然转换ArrayList到一个HashSet有效地删除重复项,如果您需要保留插入顺序,我宁愿建议您使用此变体

// list is some List of Strings
Set s = new LinkedHashSet<>(list);

然后,如果你需要取回一个List参考,您可以再次使用转换构造函数。

Matt Briançon 回复 3分钟 前

LinkedHashSet 是否保证从列表中保留几个重复项中的哪一个?例如,如果位置 1、3 和 5 在原始列表中是重复的,我们是否可以假设此过程将删除 3 和 5?或者也许删除1和3?谢谢。

abahgat 回复 3分钟 前

@Matt:是的,它确实保证了这一点。这文档说:“这个链表定义了迭代顺序,即元素插入集合的顺序(插入顺序)。请注意,如果将元素重新插入集合,则插入顺序不受影响。”

WowBow 回复 3分钟 前

很有意思。我这里有不同的情况。我不是要对字符串进行排序,而是要对另一个名为 AwardYearSource 的对象进行排序。这个类有一个叫做 year 的 int 属性。所以我想根据年份删除重复项。即,如果不止一次提到 2010 年,我想删除该 AwardYearSource 对象。我怎样才能做到这一点?

Ondrej Bozek 回复 3分钟 前

@WowBow 例如,您可以定义包含 AwardYearSource 的 Wrapper 对象。并根据 AwardYearSources 年份字段定义此 Wrapper 对象 equals 方法。然后您可以将 Set 与这些 Wrapper 对象一起使用。

shrini1000 回复 3分钟 前

@WowBow 或实现 Comparable/Comparator

0
Vitalii Fedorenko 回答 3分钟 前

在 Java 8 中:

List deduped = list.stream().distinct().collect(Collectors.toList());

请注意,hashCode-equals应遵守列表成员的合同,以使过滤正常工作。

StackFlowed 回复 3分钟 前

我如何为不区分大小写的 distinct 执行此操作?

Paul 回复 3分钟 前

@StackFlowed如果您不需要保留列表的顺序,您可以addAllnew TreeSet(String.CASE_INSENSITIVE_ORDER).添加的第一个元素将保留在集合中,因此如果您的列表包含“Dog”和“dog”(按此顺序)TreeSet将包含“狗”。如果必须保留顺序,则在答案中的行之前list.replaceAll(String::toUpperCase);.

Samir 回复 3分钟 前

我收到此错误:不兼容的类型:列表无法转换为列表

Laser Infinite 回复 3分钟 前

这通常是一个简单的解决方案,但是如何从 int[] 的 Arraylist 中删除重复项?

0
akhil_mittal 回答 3分钟 前

假设我们有一个列表String喜欢:

List strList = new ArrayList<>(5);
// insert up to five items to list.

然后我们可以通过多种方式删除重复元素。
在 Java 8 之前

List deDupStringList = new ArrayList<>(new HashSet<>(strList));

笔记:如果我们想保持插入顺序,那么我们需要使用LinkedHashSet代替HashSet
使用番石榴

List deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));

使用 Java 8

List deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());

笔记:如果我们想将结果收集到具体清单实现例如LinkedList那么我们可以将上面的例子修改为:

List deDupStringList3 = strList.stream().distinct()
                 .collect(Collectors.toCollection(LinkedList::new));

我们可以用parallelStream也在上面的代码中,但它可能不会带来预期的性能优势。检查这个问题更多。

Diablo 回复 3分钟 前

是的,当我输入我之前的评论时,我的印象是parallel streams将始终提供更好的性能。但这是一个神话。后来我了解到,在某些情况下应该使用并行流。在这种情况下,并行流不会提供任何更好的性能。是的,并行流在某些情况下可能不会给出预期的结果。List deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());在这种情况下应该是合适的解决方案

0
Benno Richters 回答 3分钟 前

如果您不想重复,请使用代替List.转换一个List到一个Set您可以使用以下代码:

// list is some List of Strings
Set s = new HashSet(list);

如果真的有必要,您可以使用相同的结构来转换Set回到一个List.

Muhammad Adil 回复 3分钟 前

同样在线程的底部,我给出了一个答案,我使用 Set for Custom Object。如果有人有像“联系人”或“学生”这样的自定义对象,可以使用对我来说很好的答案。

TheRealChx101 回复 3分钟 前

当您必须专门访问一个元素时,问题就来了。例如,当将一个对象绑定到 Android 中的列表项视图时,您会得到它的索引。所以Set不能在这里使用。

jvargas 回复 3分钟 前

当列表是对象列表时,我该如何解决这个问题

0
Nenad Bulatović 回答 3分钟 前

您也可以这样做,并保持顺序:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList(new LinkedHashSet(myArrayList));
ByWaleed 回复 3分钟 前

我认为这是删除 ArrayList 中重复项的最佳方法。绝对推荐。谢谢@Nenad 的回答。