我有一个自定义对象的ArrayList。我想删除重复的条目。
对象有三个字段:title, subtitle
和id
。如果一个字幕出现多次,我只需要带有那个副标题的第一个项目(忽略带有该副标题的剩余对象)。
答案 0 :(得分:50)
您可以使用自定义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());
}
答案 1 :(得分:46)
List list = (...);
//list may contain duplicates.
//remove duplicates if any
Set setItems = new LinkedHashSet(list);
list.clear();
list.addAll(setItems);
你可能需要覆盖“equals()”,这样如果2个元素具有相同的字幕(或者可能是字号和副标题,那么它们被视为等号)。
答案 2 :(得分:11)
我建议使用Set
http://download.oracle.com/javase/6/docs/api/java/util/Set.html
其性质不能包含重复的项目。您可以使用
从原始ArrayList创建新集Set myset = new HashSet(myArrayList);
或者,只需从头开始使用Set,不要使用ArrayList,因为它没有执行您需要的功能。
答案 3 :(得分: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);
}
}
如果元素已存在,则add()
的{p} Set
会返回false
。
答案 4 :(得分:7)
您可以使用O(n ^ 2)解决方案:使用list.iterator()
迭代列表一次,并在每次迭代时再次迭代以检查是否存在重复。如果有 - 请致电iterator.remove()
。其中一个变体是使用guava的Iterables.filter(list, predicate)
,其中过滤逻辑位于谓词中。
另一种方式(可能更好)是定义equals(..)
和hashCode(..)
方法来处理自定义相等逻辑,然后简单地构造一个new HashSet(list)
。这将清除重复。
答案 5 :(得分: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();
}
}
答案 6 :(得分:4)
删除集合中的所有重复项,同时保留订单(如果它是有序集合)。对大多数情况来说足够有效。
public static <I, T extends Collection<I>> T removeDuplicates(T collection)
{
Set<I> setItems = new LinkedHashSet<I>(collection);
collection.clear();
collection.addAll(setItems);
return collection;
}
答案 7 :(得分:2)
使用Collections.sort()对一个简单的循环进行排序和使用以捕获双精度数,例如:
docker run --volumes-from my_datastore ...
这假设您将在A类中实现Comparable。
答案 8 :(得分:2)
Java8更新:
使用Java8流你也可以非常简单。
ArrayList<String> deduped;
deduped = yourArrayList.stream()
.distinct()
.collect(Collectors.toCollection(ArrayList::new));
这比保持排序的 ArrayList → Set → ArrayList 更具优势。
答案 9 :(得分:1)
private static List<Integer> removeDuplicates(List<Integer> list) {
ArrayList<Integer> uniqueList = new ArrayList<Integer>();
for (Integer i : list) {
if (!inArray(i, uniqueList)) {
uniqueList.add(i);
}
}
return uniqueList;
}
private static boolean inArray(Integer i, List<Integer> list) {
for (Integer integer : list) {
if (integer == i) {
return true;
}
}
return false;
}
答案 10 :(得分:0)
List<YourObject> all = ******** // this is the object that you have already and filled it.
List<YourObject> noRepeat= new ArrayList<YourObject>();
for (YourObject al: all) {
boolean isPresent = false;
// check if the current objects subtitle already exists in noRepeat
for (YourObject nr : noRepeat) {
if (nr.getName().equals(al.getName()) {
isFound = true;//yes we have already
break;
}
}
if (!isPresent)
noRepeat.add(al); // we are adding if we don't have already
}
获取一个相同类型的新ArrayList对象
逐个将所有旧的arraylists元素添加到这个新的arraylist对象中 但在添加每个对象之前,请检查新的arraylist,如果有任何对象具有相同的副标题。如果新的arraylist包含这样的副标题,请不要添加它。否则加上
答案 11 :(得分:0)
解决方案取决于具体情况。
如果您没有太多数据,请使用Set Set<T> unique = new HashSet<>(yourList);
(如果您关心订单,请使用LinkedHashSet。它会创建一个新集合,但通常不会有问题。
如果要修改现有列表并且不想/不能创建新集合,可以删除重复项,如下所示:
List<Integer> numbers =
new ArrayList<>(asList(1, 1, 2, 1, 2, 3, 5));
System.out.println("Numbers: " + numbers);
ListIterator<Integer> it = numbers.listIterator();
while (it.hasNext()) {
int i = it.nextIndex();
Integer current = it.next();
for (int j = 0; j < i; ++j) {
if (current.equals(numbers.get(j))) {
it.remove();
break;
}
}
}
System.out.println("Unique: " + numbers);
它适用于O(n ^ 2),但它有效。类似的实现,但更简单,是在列表排序时 - 在O(n)时间内工作。这两种实现都在Farenda中解释:remove duplicates from list - various implementations。
答案 12 :(得分:0)
使用Java 8流的另一种方法也可以做得很酷:
List<Customer> CustomerLists;
List<Customer> unique = CustomerLists.stream().collect(collectingAndThen(
toCollection(() -> new TreeSet<>(comparingLong(Customer::getId))),
ArrayList::new));
答案 13 :(得分:0)
在Java 8中,您还可以执行以下操作:
"name"
诀窍是收集要映射的流,并提供始终返回其第一个参数的关键冲突解析器lambda(yourList.stream().collect(
Collectors.toMap(
obj -> obj.getSubtitle(),
Function.identity(),
(o1,o2) -> o1))
.values();
)。
结果是一个Collection,而不是一个List,但是您可以轻松地将其转换为List:
(o1,o2) -> o1