在我发布这个问题之前,我发现有点类似的问题发布here。但答案是基于String。不过,我在这里有不同的情况。我不是想要删除String,而是另一个名为AwardYearSource的对象。这个类有一个int属性叫做year。所以我想根据年份删除重复项目。即如果2010年有不止一次提及,我想删除该AwardYearSource对象。我怎样才能做到这一点?如何从基于自定义Java对象而不是基元类型的列表中删除重复项?
回答
删除基于字段内容如下(维持秩序)的最简单方法:
Map<Integer, AwardYearSource> map = new LinkedHashMap<>();
for (AwardYearSource ays : list) {
map.put(ays.getYear(), ays);
}
list.clear();
list.addAll(map.values());
你可以使用地图和存储您的对象与去年作为重点:
Map<Integer, AwardYearSource> map = new HashMap<Integer, AwardYearSource>();
map.put(someAwardYearSource1.getYear(), someAwardYearSource1);
map.put(someAwardYearSource2.getYear(), someAwardYearSource2);
etc.
在结束时,地图将在今年包含唯一的值,您可以用数值方法调用:
Collection<AwardYearSource> noDups = map.values();
用int作为键类型,将你的类作为值类型创建一个HashMap对象。然后遍历该列表,并使用每一个元素插入到地图中:
mymap.put(source.year, source);
然后从原著列表中删除所有的元素和迭代在地图上,并插入每个元素到列表中。
真的吗?你能否提供更多细节?尽管至少有一个迭代器是不必要的 - 请参阅其他一些答案。如果在线程环境中使用,这会产生一些令人讨厌的副作用。 – 2012-04-16 15:59:52
也许您已在满错误的答案上发布此评论?我在我的解决方案中没有看到任何迭代器,并且它非常安全。 – smichak 2012-04-16 16:10:55
您明确提到迭代,并且您将至少使用一个_implicit_(在for-each构造的情况下生成的编译器)迭代器。如果这是打包在自己的方法(它应该是),然后从原始列表中删除项目是绝对不**线程安全。 – 2012-04-16 16:40:51
另一种方法是覆盖hashCode()
和equals(Object obj)
为您的对象。既然它只有一个你想用来确定平等的领域,这是非常简单的。喜欢的东西:
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof AwardYearSource)) {
return false;
}
return (this.year == ((AwardYearSource)obj).year);
}
public int hashCode() {
return this.year;
}
然后,你可以坚持所有的对象为Set
删除重复:
Set<AwardYearSource> set = new Set<AwardYearSource>();
set.add(new AwardYearSource(2011));
set.add(new AwardYearSource(2012));
set.add(new AwardYearSource(2011));
for (AwardYearSource aws : set) {
System.out.println(aws.year);
}
如果您AwardYearSource类重写equals和hashCode方法(Eclipse可以同时生成),然后你可以将它们添加到Set。该集不会包含任何重复。
public class AwardYearSource
{
private final int year;
public AwardYearSource(int year)
{
this.year = year;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + year;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AwardYearSource other = (AwardYearSource) obj;
if (year != other.year)
return false;
return true;
}
@Override
public String toString()
{
return String.valueOf(year);
}
public static void main(String[] args)
{
Set<AwardYearSource> set = new HashSet<AwardYearSource>();
set.add(new AwardYearSource(2000));
set.add(new AwardYearSource(2000));
set.add(new AwardYearSource(2000));
set.add(new AwardYearSource(2000));
System.out.println(set);
}
}
输出是[2000]。集合中只有一个项目。
相当简单。尽管有些东西让我误解了地图版本(不是我怀疑他们会工作,但它似乎有点矫枉过正,尽管这个版本在这方面不一定更好)。
答案是功能性和线程安全的(假设AwardYearSource
是不可变的)。
public static List<AwardYearSource> removeDuplicateYears(
final Collection<AwardYearSource> awards) {
final ArrayList<AwardYearSource> input = new ArrayList<AwardYearSource>(awards);
// If there's only one element (or none), guaranteed unique.
if (input.size() <= 1) {
return input;
}
final HashSet<Integer> years = new HashSet<Integer>(input.size(), 1);
final Iterator<AwardYearSource> iter = input.iterator();
while(iter.hasNext()) {
final AwardYearSource award = iter.next();
final Integer year = award.getYear();
if (years.contains(year)) {
iter.remove();
} else {
years.add(year);
}
}
return input;
}
决赛圈太多了 – 2012-04-16 18:21:33
Set<Integer> set = new HashSet<>();
list.removeIf(i -> set.contains(i.getYear()) ? true : !set.add(i.getYear()));
这应该有助于其中,复制是基于特定的属性(或属性的组合)决定,今年在这种情况下。希望这可以帮助。
- 1. 从列表中删除基于特定列的重复行
- 2. T-SQL基于列删除重复项
- 3. 的Java TreeSet中删除重复的基于对象的属性
- 4. 基于值的权重从JSON对象中删除重复值
- 5. 如何根据两个自定义对象删除列表中的重复项
- 6. 如何基于列的值从完全删除数据表中的重复项?
- 7. 如何实现基于ArrayList.util而不能删除元素的自定义ArrayList
- 8. 删除基于“分组”的重复项?
- 9. 基于对象标识删除重复的类实例
- 10. 删除对象列表中的重复项而不依赖于集合
- 11. 如何使用java从bean中删除基于id的重复项?
- 12. 如何从基于键的散列数组中删除重复项?
- 13. 从基于索引的选定列表中删除选项?
- 14. 从列表中删除重复项从<T> C#.net基于属性值
- 15. 如何删除基于两个不同列的重复值?
- 16. 删除基于Ruby中的列的重复项
- 17. 如何从基于多个表的Oracle结果集中删除重复项
- 18. python从列表中删除基于其他列表的元素
- 19. 排序基于自定义对象中的ArrayList列表
- 20. 如何从Java中java.lang类型的对象中获取等价基元类型?
- 21. 反复从类对象(Python)中的列表中删除项目
- 22. 定义基于元素类型的XPath
- 23. 从基于ID的fasta文件中删除重复的序列
- 24. 在基于一列的html表格中删除重复的行
- 25. TypeError:不可用类型:'list',删除列表中的重复项
- 26. 在ArrayList中存储具有不同基元类型的自定义对象
- 27. GroupBy从IEnumerable对象列表中删除重复项
- 28. 删除基于几个对象属性从列表
- 29. 排序列表对象基于对象的数据类型
- 30. 删除基于列值的重复项-linq
Java的8路也相当不错:http://stackoverflow.com/questions/23699371/java-8-distinct-by-property – JDC 2016-12-09 07:53:32