如何按数组第二个元素对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
相关产品推荐
相关产品推荐

