You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ArrayList中属性唯一的TwoNumbers对象复制到新ArrayList

这个问题很典型——Java里默认是按对象引用地址判断相等性的,哪怕两个TwoNumbers对象的num1、num2数值完全一样,只要是不同实例,就会被当成不同的对象。要解决这个问题,核心是告诉Java:「当两个TwoNumbers对象的num1和num2都相等时,它们就是同一个逻辑对象」,具体要做两步:重写equals()和hashCode()方法,然后用合适的方式去重。

下面一步步来:

第一步:重写TwoNumbers类的equals()和hashCode()

Java的集合类(比如HashSet、ArrayList的contains方法)判断元素是否重复,依赖的就是这两个方法:

  • equals()用来判断两个对象逻辑上是否相等
  • hashCode()用来快速分组(比如HashSet会先比较哈希值,再用equals确认)

给你写个完整的TwoNumbers示例:

import java.util.Objects;

public class TwoNumbers {
    private int num1;
    private int num2;

    // 构造方法
    public TwoNumbers(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

    // Getter方法(如果需要的话)
    public int getNum1() {
        return num1;
    }

    public int getNum2() {
        return num2;
    }

    // 重写equals方法
    @Override
    public boolean equals(Object o) {
        // 如果是同一个引用,直接返回true
        if (this == o) return true;
        // 如果对象为null,或者不是TwoNumbers类型,返回false
        if (o == null || getClass() != o.getClass()) return false;
        // 强转为TwoNumbers,比较num1和num2
        TwoNumbers that = (TwoNumbers) o;
        return num1 == that.num1 && num2 == that.num2;
    }

    // 重写hashCode方法
    @Override
    public int hashCode() {
        // 用Objects工具类结合num1和num2生成哈希值
        return Objects.hash(num1, num2);
    }
}

这里要注意:如果你的num1/num2是包装类型(比如Integer),equals里要用Objects.equals(num1, that.num1)而不是==,避免空指针和值相等但引用不同的问题。

第二步:实现ArrayList的去重复制

有两种常用方式,选哪种看你的需求:

方式一:用HashSet自动去重(简单高效)

HashSet会自动过滤掉重复元素,依赖我们刚才重写的equals和hashCode。把原ArrayList的元素放进HashSet,再转成新的ArrayList就行:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 原ArrayList,假设已经存了一些TwoNumbers对象
        List<TwoNumbers> originalList = new ArrayList<>();
        originalList.add(new TwoNumbers(1, 2));
        originalList.add(new TwoNumbers(3, 4));
        originalList.add(new TwoNumbers(1, 2)); // 重复元素

        // 用HashSet去重
        HashSet<TwoNumbers> uniqueSet = new HashSet<>(originalList);
        // 转成新的ArrayList
        List<TwoNumbers> uniqueList = new ArrayList<>(uniqueSet);

        // 测试输出,会发现只保留了两个不重复的对象
        for (TwoNumbers num : uniqueList) {
            System.out.println(num.getNum1() + ", " + num.getNum2());
        }
    }
}

这种方式优点是代码简洁,效率高,缺点是会打乱原列表的顺序(因为HashSet是无序的)。如果需要保留原顺序,可以用LinkedHashSet代替HashSet,它会保留元素插入的顺序。

方式二:手动遍历检查(保留原顺序,适合小列表)

如果要严格保留原列表中元素的出现顺序,也可以手动遍历原列表,每次检查新列表里是否已经存在相同属性的对象:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<TwoNumbers> originalList = new ArrayList<>();
        originalList.add(new TwoNumbers(1, 2));
        originalList.add(new TwoNumbers(3, 4));
        originalList.add(new TwoNumbers(1, 2));

        List<TwoNumbers> uniqueList = new ArrayList<>();
        for (TwoNumbers num : originalList) {
            // 调用contains时,会用到我们重写的equals方法判断是否存在
            if (!uniqueList.contains(num)) {
                uniqueList.add(num);
            }
        }

        // 输出会和原列表顺序一致,且去重
        for (TwoNumbers num : uniqueList) {
            System.out.println(num.getNum1() + ", " + num.getNum2());
        }
    }
}

这种方式的优点是保留原顺序,缺点是效率低一点(每次contains都要遍历新列表),适合元素数量不多的场景。

额外注意点

如果你的num1或num2是自定义的引用类型(比如不是Integer、String这些已经重写了equals/hashCode的类),那对应的类也必须重写equals和hashCode方法,否则还是会按引用判断相等性,导致去重失败。

内容的提问来源于stack exchange,提问作者Qwisatz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:41:02