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

如何按数组第二个元素对ArrayList<Integer[]>去重并保留首元素最小值

按数组第二个元素分组去重,保留第一个元素最小的数组

嘿,这个场景用普通的Set确实搞不定——毕竟数组的equals是按引用判断的,而且咱们的需求也不是单纯去重,而是按第二个元素分组,每组里挑第一个元素最小的数组。我给你两种实用的实现方式,你可以根据自己的Java版本来选:

方法一:传统遍历 + HashMap(兼容所有Java版本)

核心思路是用HashMap来做分组:key存数组的第二个元素(也就是咱们要分组的依据),value存当前组里第一个元素最小的那个数组。遍历原列表的时候,逐个判断更新map里的内容就行。

代码示例:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        List<Integer[]> list = new ArrayList<>();
        list.add(new Integer[] {13, 1});
        list.add(new Integer[] {100, 2});
        list.add(new Integer[] {143, 2});
        list.add(new Integer[] {185, 3});
        list.add(new Integer[] {111, 3});
        list.add(new Integer[] {98, 4});

        // 用HashMap分组,key是第二个元素,value是当前组最小的数组
        Map<Integer, Integer[]> resultMap = new HashMap<>();
        for (Integer[] arr : list) {
            int groupKey = arr[1];
            int currentFirst = arr[0];
            // 如果map里没有这个key,直接放入;如果有,比较第一个元素,留小的
            if (!resultMap.containsKey(groupKey)) {
                resultMap.put(groupKey, arr);
            } else {
                Integer[] existingArr = resultMap.get(groupKey);
                if (currentFirst < existingArr[0]) {
                    resultMap.put(groupKey, arr);
                }
            }
        }

        // 把map的value转成最终的List
        List<Integer[]> finalList = new ArrayList<>(resultMap.values());

        // 验证结果
        for (Integer[] arr : finalList) {
            System.out.println(Arrays.toString(arr));
        }
    }
}

运行后会输出:[13, 1]、[100, 2]、[111, 3]、[98, 4],完全符合需求。

方法二:Java 8+ Stream API(更简洁)

如果你的项目用的是Java 8及以上,用Stream的分组+收集器可以一行搞定核心逻辑,代码更简洁:

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        List<Integer[]> list = new ArrayList<>();
        list.add(new Integer[] {13, 1});
        list.add(new Integer[] {100, 2});
        list.add(new Integer[] {143, 2});
        list.add(new Integer[] {185, 3});
        list.add(new Integer[] {111, 3});
        list.add(new Integer[] {98, 4});

        List<Integer[]> finalList = list.stream()
            // 按数组第二个元素分组
            .collect(Collectors.groupingBy(
                arr -> arr[1],
                // 每组里选第一个元素最小的数组
                Collectors.minBy(Comparator.comparingInt(arr -> arr[0]))
            ))
            // 把分组后的Optional值取出并转成List
            .values().stream()
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(Collectors.toList());

        // 验证结果
        for (Integer[] arr : finalList) {
            System.out.println(Arrays.toString(arr));
        }
    }
}

这里用Collectors.minBy来获取每组中第一个元素最小的数组,因为minBy返回的是Optional(避免空组的情况),所以需要额外处理空值——不过咱们的原列表非空,filter其实可以省略,但加上会更严谨。

为什么转Set没用?

顺便说下你提到的转Set思路:普通HashSet判断元素相等是靠equals()和hashCode(),但数组的equals()是比较对象引用,不是内容——哪怕两个数组的元素完全一样,只要是不同的对象,Set都会把它们当成不同元素存进去。而且咱们的需求不是去重相同内容的数组,而是按第二个元素分组筛选,所以Set完全不适用这个场景~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:23:58