用Java ArrayList实现一个简单的数组去重功能

方案1:双层循环遍历去重(不依赖其他集合,纯ArrayList)

思路:

  1. 创建新的 ArrayList 存放结果
  2. 遍历原集合每一个元素
  3. 新集合中不存在该元素才添加,自动去重
java 复制代码
import java.util.ArrayList;

public class ArrayListDistinct1 {
    public static void main(String[] args) {
        // 原数组,包含重复数据
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(2);
        list.add(3);
        list.add(1);
        list.add(4);
        list.add(3);

        System.out.println("去重前:" + list);
        ArrayList<Integer> newList = distinctByLoop(list);
        System.out.println("去重后:" + newList);
    }

    /**
     * 双层循环去重,保留原有顺序
     */
    public static <E> ArrayList<E> distinctByLoop(ArrayList<E> oldList) {
        ArrayList<E> result = new ArrayList<>();
        for (E item : oldList) {
            // 新集合没有当前元素才添加
            if (!result.contains(item)) {
                result.add(item);
            }
        }
        return result;
    }
}

输出:

复制代码
去重前:[1, 2, 2, 3, 1, 4, 3]
去重后:[1, 2, 3, 4]

优点:仅使用 ArrayList,不引入其他类;保留插入顺序

缺点:contains() 底层遍历,数据量大性能差 O(n²)

方案2:借助 HashSet 快速去重(性能更高,推荐)

思路:Set 天然不允许重复元素,中转去重后转回 ArrayList

java 复制代码
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class ArrayListDistinct2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("苹果");
        list.add("香蕉");
        list.add("苹果");
        list.add("橙子");
        list.add("香蕉");

        System.out.println("去重前:" + list);
        ArrayList<String> distinctList = distinctBySet(list);
        System.out.println("去重后:" + distinctList);
    }

    public static <E> ArrayList<E> distinctBySet(ArrayList<E> oldList) {
        // Set自动去重
        Set<E> set = new HashSet<>(oldList);
        // 转回ArrayList
        return new ArrayList<>(set);
    }
}

注意:HashSet 会打乱原有元素顺序。

如果需要【去重+保留顺序】用 LinkedHashSet

java 复制代码
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

public class DistinctOrder {
    public static <E> ArrayList<E> distinctKeepOrder(ArrayList<E> oldList) {
        Set<E> set = new LinkedHashSet<>(oldList);
        return new ArrayList<>(set);
    }

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(3);
        list.add(5);
        list.add(1);
        ArrayList<Integer> res = distinctKeepOrder(list);
        System.out.println(res); // [5, 3, 1] 顺序不变
    }
}

方案3:Java8 Stream一行代码去重(最简写法)

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class StreamDistinct {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(2);
        list.add(7);
        list.add(7);
        list.add(9);

        // distinct() 去重,collect转回ArrayList
        List<Integer> distinctList = list.stream()
                .distinct()
                .toList();

        System.out.println(distinctList);
    }
}

总结对比

方式 优点 缺点
双层循环contains 只使用ArrayList、有序 大数据效率低
LinkedHashSet 效率高、有序 需要导入Set集合
Stream distinct 代码极简 JDK8+支持