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

遍历HashMap获取字符-整数有序列表时仅得重复元素的问题

HashMap遍历取最小元素时重复输出单一元素的问题

我在Java中遍历HashMap,想按整数从小到大的顺序获取对应的字符列表,但结果只得到一个元素重复出现。我的思路是每次找到当前最小的非0值键值对后,用itr.remove()把它从Map中移除,这样下次迭代就能找下一个最小的。

问题代码

Iterator<Map.Entry<Character, Integer>> itr = myHashMap.entrySet().iterator();

while(itr.hasNext()) {
    Map.Entry<Character, Integer> entry = itr.next();
    for (int i = 0; i < newCharArray2.length; i++) {
        if (entry.getValue() < min && entry.getValue() != 0) {
            min = entry.getValue();
            k = entry.getKey();
            itr.remove();
        }
        newCharArray2[i] = k;
        letterCount[i] = min;
    }
}

System.out.println("New newCharArray letters: " + Arrays.toString(newCharArray2));
System.out.println("New letterCount numbers: " + Arrays.toString(letterCount));

相关数据

  • 字母计数数组(对应A-K):
    [1, 2, 0, 2, 0, 0, 0, 2, 0, 0, 1]
    
  • HashMap初始化代码:
    myHashMap.put('A', letterCount[0]);
    myHashMap.put('B', letterCount[1]);
    myHashMap.put('C', letterCount[2]);
    myHashMap.put('D', letterCount[3]);
    myHashMap.put('E', letterCount[4]);
    myHashMap.put('F', letterCount[5]);
    myHashMap.put('G', letterCount[6]);
    myHashMap.put('H', letterCount[7]);
    myHashMap.put('I', letterCount[8]);
    myHashMap.put('J', letterCount[9]);
    myHashMap.put('K', letterCount[10]);
    

实际输出

New newCharArray letters: [A, A, A, A, A]
New letterCount numbers: [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]

问题分析

你的代码逻辑存在核心错误:

  1. 嵌套循环顺序错误:外层迭代器每次仅取一个entry,但内层直接遍历整个newCharArray2数组,把当前的k和min填充到所有位置。这导致第一次拿到的元素(A,值1)直接覆盖整个数组,后续迭代的修改完全无法生效。
  2. min的逻辑矛盾:如果min默认是int初始值0,entry.getValue() < min对所有非0值都不成立;即便你提前把min设为大数,内层循环的覆盖问题依然会让数组全是第一个元素。
  3. itr.remove()时机错误:在数组遍历循环中就移除当前entry,后续迭代的entry根本没机会修改已经被填满的数组。

正确解决方案

没必要用迭代器边遍历边删除,更高效的方式是先过滤、排序,再填充数组:

方案1:Stream API实现(Java 8+)

import java.util.stream.Collectors;
import java.util.List;

// 过滤非0元素并按值从小到大排序
List<Map.Entry<Character, Integer>> sortedEntries = myHashMap.entrySet().stream()
    .filter(entry -> entry.getValue() != 0)
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toList());

// 填充目标数组(避免数组越界)
for (int i = 0; i < sortedEntries.size() && i < newCharArray2.length; i++) {
    Map.Entry<Character, Integer> entry = sortedEntries.get(i);
    newCharArray2[i] = entry.getKey();
    letterCount[i] = entry.getValue();
}

// 输出结果
System.out.println("New newCharArray letters: " + Arrays.toString(newCharArray2));
System.out.println("New letterCount numbers: " + Arrays.toString(letterCount));

方案2:传统方式(兼容低版本Java)

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

// 过滤出非0的键值对
List<Map.Entry<Character, Integer>> entryList = new ArrayList<>();
for (Map.Entry<Character, Integer> entry : myHashMap.entrySet()) {
    if (entry.getValue() != 0) {
        entryList.add(entry);
    }
}

// 按值从小到大排序
Collections.sort(entryList, new Comparator<Map.Entry<Character, Integer>>() {
    @Override
    public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
});

// 填充数组
for (int i = 0; i < entryList.size() && i < newCharArray2.length; i++) {
    Map.Entry<Character, Integer> entry = entryList.get(i);
    newCharArray2[i] = entry.getKey();
    letterCount[i] = entry.getValue();
}

说明

  • 先过滤值为0的元素,避免无效处理;
  • 通过排序直接得到按值从小到大的有序列表,无需手动查找最小值;
  • 遍历排序后的列表依次填充数组,即可得到有序的字符和对应数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:21