如何从列表中删除重复项<object>
How to remove duplicates from list<object>
我在 java 中有一个名为 foo 的对象。
我可以做 foo.getDate();
,这会给我一个项目的日期。
但是现在我有一个 list<foo>
并且我想为每个项目获取一个日期。
因此,如果我遍历我的列表,我将看到这个输出:
3-1-2015
3-1-2015
5-1-2015
8-1-2015
8-1-2015
但我想看:
3-1-2015
5-1-2015
8-1-2015
所以我希望只将具有唯一日期的第一项添加到列表中。
我如何在 Java 中执行此操作?
提前致谢!
可能最简单的方法是使用地图(例如 HashMap
)...使用 Date 作为键,然后将所有 Foo 对象放入其中。然后,每次一个键已经存在时,该值将被覆盖,并且每个 Date 最终只有一个 Foo 对象。如果你需要一个列表(例如排序),你可以做类似 new ArrayList<Foo>( myMap.values() );
then.
创建将存储唯一日期的集合。如果您的 foo 实例中的日期尚未添加到设置中,请将此实例添加到包含具有唯一日期的 foo 对象的列表中。
List<Foo> list = new ArrayList<>();
//fill list with your foo instances
Set<Date> uniqueDates = new HashSet<>();
List<Foo> resultList = new ArrayList<>();
for (Foo f : list){
if (uniqueDates.add(f.getDate())){//if I was able to add date to set
//it means that instance with this date is seen first time
//so I can add it to result list
resultList.add(f);
}
}
好吧,您可能应该为此使用 Set
。
只是添加到@Pshemo 的答案中,对 Java 8 做同样的事情很简单:
public class RemoveDuplicates {
public static void main(String[] args) {
// Initialize some dates
long now = System.currentTimeMillis();
Date d1 = new Date(now);
Date d2 = new Date(now - 10_000_000_000L);
Date d3 = new Date(now - 100_000_000_000L);
// Initialize some Foos with the dates
List<Foo> list = new ArrayList<>(Arrays.asList(
new Foo(d3), new Foo(d3), new Foo(d2),
new Foo(d1), new Foo(d1)));
Set<Date> uniqueDates = new HashSet<>();
// Filter foos whose date is already in the set
List<Foo> distinct = list.stream().filter(
f -> uniqueDates.add(f.getDate())).
collect(Collectors.toList());
System.out.println(distinct); // [Foo [date=17/01/12],
// Foo [date=24/11/14],
// Foo [date=19/03/15]]
}
static class Foo {
private static DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT);
private final Date date;
Date getDate() {
return this.date;
}
Foo(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Foo [date=" + formatter.format(this.date) + "]";
}
}
}
原理完全相同:如果日期已经在集合中,则Foo
从流中过滤。
我在 java 中有一个名为 foo 的对象。
我可以做 foo.getDate();
,这会给我一个项目的日期。
但是现在我有一个 list<foo>
并且我想为每个项目获取一个日期。
因此,如果我遍历我的列表,我将看到这个输出:
3-1-2015
3-1-2015
5-1-2015
8-1-2015
8-1-2015
但我想看:
3-1-2015
5-1-2015
8-1-2015
所以我希望只将具有唯一日期的第一项添加到列表中。 我如何在 Java 中执行此操作?
提前致谢!
可能最简单的方法是使用地图(例如 HashMap
)...使用 Date 作为键,然后将所有 Foo 对象放入其中。然后,每次一个键已经存在时,该值将被覆盖,并且每个 Date 最终只有一个 Foo 对象。如果你需要一个列表(例如排序),你可以做类似 new ArrayList<Foo>( myMap.values() );
then.
创建将存储唯一日期的集合。如果您的 foo 实例中的日期尚未添加到设置中,请将此实例添加到包含具有唯一日期的 foo 对象的列表中。
List<Foo> list = new ArrayList<>();
//fill list with your foo instances
Set<Date> uniqueDates = new HashSet<>();
List<Foo> resultList = new ArrayList<>();
for (Foo f : list){
if (uniqueDates.add(f.getDate())){//if I was able to add date to set
//it means that instance with this date is seen first time
//so I can add it to result list
resultList.add(f);
}
}
好吧,您可能应该为此使用 Set
。
只是添加到@Pshemo 的答案中,对 Java 8 做同样的事情很简单:
public class RemoveDuplicates {
public static void main(String[] args) {
// Initialize some dates
long now = System.currentTimeMillis();
Date d1 = new Date(now);
Date d2 = new Date(now - 10_000_000_000L);
Date d3 = new Date(now - 100_000_000_000L);
// Initialize some Foos with the dates
List<Foo> list = new ArrayList<>(Arrays.asList(
new Foo(d3), new Foo(d3), new Foo(d2),
new Foo(d1), new Foo(d1)));
Set<Date> uniqueDates = new HashSet<>();
// Filter foos whose date is already in the set
List<Foo> distinct = list.stream().filter(
f -> uniqueDates.add(f.getDate())).
collect(Collectors.toList());
System.out.println(distinct); // [Foo [date=17/01/12],
// Foo [date=24/11/14],
// Foo [date=19/03/15]]
}
static class Foo {
private static DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT);
private final Date date;
Date getDate() {
return this.date;
}
Foo(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Foo [date=" + formatter.format(this.date) + "]";
}
}
}
原理完全相同:如果日期已经在集合中,则Foo
从流中过滤。