从ArrayLists中删除重复项

Byt*_*ode 22 java

我有一个自定义对象的ArrayList.我想删除重复的条目.

对象有三个字段:title, subtitleid.如果一个字幕出现多次,我只需要带有那个副标题的第一个项目(忽略带有该副标题的剩余对象).

Ric*_*ssu 52

您可以使用自定义Comparator将ArrayList的内容放在TreeSet中,如果两个字幕相同,则应返回0.之后,您可以转换列表中的Set并使列表没有"重复".这是Object的一个例子,当然你应该使用正确的类和逻辑.

public void removeDuplicates(List<Object> l) {
    // ... the list is already populated
    Set<Object> s = new TreeSet<Object>(new Comparator<Object>() {

        @Override
        public int compare(Object o1, Object o2) {
            // ... compare the two object according to your requirements
            return 0;
        }
    });
            s.addAll(l);
    List<Object> res = Arrays.asList(s.toArray());
}
Run Code Online (Sandbox Code Playgroud)

  • 你是对的,我忘了一条线,现在代码是正确的.至于重写equals和hashset,我不同意作为一般解决方案; 覆盖它们比我的解决方案更具侵入性,即使你不能修改原始类,它也会起作用.无论如何,我接受-1发布错误的代码; 我总是对评论家开放 (2认同)

Tri*_*tan 46

List list = (...);

//list may contain duplicates.

//remove duplicates if any
Set setItems = new LinkedHashSet(list);
list.clear();
list.addAll(setItems);
Run Code Online (Sandbox Code Playgroud)

您可能需要覆盖"equals()",以便如果2个元素具有相同的字幕(或者可能是tite和subtitle),则认为它们是等于的

  • +1.此解决方案维护原始列表的顺序 (11认同)

Cod*_*nci 11

我建议使用Set

http://download.oracle.com/javase/6/docs/api/java/util/Set.html

其本质上不能包含重复的项目.您可以使用原始ArrayList创建新集

Set myset = new HashSet(myArrayList);
Run Code Online (Sandbox Code Playgroud)

或者,只需从头开始使用Set,不要使用ArrayList,因为它没有执行您需要的功能.

  • 如果那个属性是将对象标记为唯一的,那么他为什么不重写equals以便它只检查一个属性? (3认同)

Aar*_*lla 10

List<Item> result = new ArrayList<Item>();
Set<String> titles = new HashSet<String>();

for(Item item : originalList) {
    if(titles.add(item.getTitle()) {
        result.add(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

add()如果元素已存在则Set返回false


Boz*_*zho 7

您可以使用O(n ^ 2)解决方案:使用list.iterator()迭代列表一次,并在每次迭代时再次迭代它以检查是否存在重复.如果有 - 打电话iterator.remove().这种方法的一个变体是使用guava Iterables.filter(list, predicate),其中过滤逻辑在谓词中.

另一种方法(也许更好)是定义equals(..)hashCode(..)方法来处理您的自定义逻辑平等,然后简单地构建new HashSet(list).这将清除重复.


Whi*_*g34 6

如果我理解你有一个ArrayList<Custom>,让我们称之为list.你的Custom班级有一个字幕字段,让我们说一个getSubtitle()返回的方法String.您只想保留第一个唯一的字幕并删除任何剩余的副本.这是你如何做到这一点:

Set<String> subtitles = new HashSet<String>();
for (Iterator<Custom> it = list.iterator(); it.hasNext(); ) {
    if (!subtitles.add(it.next().getSubtitle())) {
        it.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)