Android/Java中如何去除自定义Model类ArrayList重复元素?
给自定义Model的ArrayList去重的几种实用方法
嘿,我明白你现在的需求——给自定义Model的ArrayList去除重复元素,而且你之前还试过用HashSet结合String处理过Person类的去重对吧?既然你对Android/Java的集合操作不太熟悉,我给你梳理几种靠谱、常用的方法,一步步来:
方法一:重写Model的equals()和hashCode(),用HashSet去重(最推荐)
这是Java集合去重的标准做法,因为HashSet的核心就是通过哈希值和equals判断元素是否重复。敲黑板:如果不重写这两个方法,HashSet会默认比较对象的内存地址,就算两个Model的字段完全一致,也会被当成不同元素!
步骤:
- 在你的自定义Model类(比如Person)里重写
equals()和hashCode(),根据你认为“重复”的字段来实现(比如name+age都相同就算重复)。 - 把原ArrayList转成HashSet(或者LinkedHashSet,能保留原列表的顺序),再转回ArrayList即可。
代码示例:
// 自定义Person类 public class Person { private String name; private int age; // 构造方法、getter/setter 自行补充 @Override public boolean equals(Object o) { // 先判断是否是同一个对象 if (this == o) return true; // 判断是否为null或者类型不同 if (o == null || getClass() != o.getClass()) return false; // 强转后比较字段 Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { // 根据参与判断重复的字段生成哈希值 return Objects.hash(name, age); } } // 去重逻辑 ArrayList<Person> originalList = new ArrayList<>(); // 假设你已经给originalList添加了元素 // 用LinkedHashSet保持原列表顺序,HashSet是无序的 LinkedHashSet<Person> uniqueSet = new LinkedHashSet<>(originalList); ArrayList<Person> deduplicatedList = new ArrayList<>(uniqueSet);
方法二:用Stream API去重(Java 8+/Android API 24+)
如果你的项目支持Java 8及以上(Android可以通过开启Desugar支持低版本),Stream的distinct()方法能快速实现去重:
情况1:已经重写了equals/hashCode
ArrayList<Person> deduplicatedList = originalList.stream() .distinct() .collect(Collectors.toCollection(ArrayList::new));
情况2:不想重写equals/hashCode
可以结合filter()和一个辅助Set来判断重复,比如通过拼接字段的方式(类似你之前用String的思路,但更简洁):
Set<String> seenKeys = new HashSet<>(); ArrayList<Person> deduplicatedList = originalList.stream() .filter(person -> seenKeys.add(person.getName() + "_" + person.getAge())) .collect(Collectors.toCollection(ArrayList::new));
这里的seenKeys.add()会返回false如果元素已存在,从而过滤掉重复项。
方法三:手动遍历去重(兼容所有版本)
如果你的项目是Android低版本,没法用Stream,或者不想依赖HashSet,手动遍历也是个稳妥的选择:
ArrayList<Person> deduplicatedList = new ArrayList<>(); for (Person current : originalList) { boolean isDuplicate = false; // 遍历新列表,判断当前元素是否已存在 for (Person existing : deduplicatedList) { // 这里根据你的需求定义重复规则,比如name和age相同就算重复 if (current.getName().equals(existing.getName()) && current.getAge() == existing.getAge()) { isDuplicate = true; break; } } if (!isDuplicate) { deduplicatedList.add(current); } }
关于你之前用String的方法
你之前通过把Person转成String来用HashSet去重,思路是对的,但这种方法容易出问题——比如字段里有特殊字符(比如下划线、减号),拼接后可能会出现不同对象生成相同String的情况,或者相同对象生成不同String的情况,所以还是更推荐上面的方法哦。
内容的提问来源于stack exchange,提问作者Super Man
相关产品推荐
相关产品推荐

