尝试从返回 null 的哈希映射值数组中创建哈希映射键数组

时间:2021-03-14 11:32:15

标签: java loops sorting hashmap bubble-sort

我创建了一个方法,它将哈希图作为输入,将值转换为数组,使用冒泡排序对数组进行排序,然后我希望它使用排序后的值从初始哈希图中选择前 N 个索引键.我知道这不是最好的方法,但没关系(我已经编写了此方法作为替代方法)。

该方法返回 null,因为 maxItems 为空且“System.out.println(entry.getKey());”不会向控制台打印任何内容。

感谢您的帮助!

public String[] getMaxListAlt(int n, HashMap itemCount) {

    itemCount.values().toArray();

    Integer[] maxArray = itemCount.values().toArray(new Integer[0]);

    int length = maxArray.length;
    for (int i = 0; i < length-1; i++)
        for (int j = 0; j < length-i-1; j++)
            if (maxArray[j] > maxArray[j+1])
            {
                int temp = maxArray[j];
                maxArray[j] = maxArray[j+1];
                maxArray[j+1] = temp;
                
            }

    String[] maxItems = new String[n];
    int maxIndex = n-1;
    System.out.println(maxIndex);


    for (int i=0; i >= n-1; i++) {
        for (Map.Entry<String, Integer> entry : itemCount.entrySet()) {
            if (entry.getValue().equals(maxArray[i])) {
                System.out.println(entry.getKey());
                maxItems[i] = entry.getKey();
            }
        }
    }

        for (int counts : maxArray) {

        System.out.println(counts);

    }

    return maxItems;
}

2 个答案:

答案 0 :(得分:2)

您的 for 循环无法运行,因为您输入了拼写错误 - int i=0; i>= n-1;,但您的 i 永远不能大于您的 n-1。相反:

for (int i=0; i <= n-1; i++) {
    for (Map.Entry<String, Integer> entry : itemCount.entrySet()) {

答案 1 :(得分:1)

如果我理解您要做什么,这里是您可能感兴趣的另一种方法。但是,您似乎做错了几件事。

  1. 您的冒泡排序按升序排序,我认为您不想要。
  2. 当循环通过 entrySet 时,您会得到重复的值,因为您总是以特定数字到达第一个值。但它可能会重复你已有的东西。

以下流媒体流程是这样工作的。

  • 首先它流式传输字符串数组
  • 然后使用 groupingBy
  • 创建基于映射的频率计数
  • 然后它流式传输 entryset 并根据值(计数)按降序排序
  • 然后它将条目数限制为 n 并将键映射到流
  • 并返回数组中的那些键。

创建一些测试数据

Random r = new Random();
String[] v = r.ints(100, 'a', 'z' + 1)
        .mapToObj(c -> (char) c + "").toArray(String[]::new);

int n = 10;

流媒体过程

Map<String, Long> itemCount = Arrays.stream(v)
        .collect(Collectors.groupingBy(a -> a, Collectors.counting()));
        
String[] result = itemCount.entrySet()
        .stream()
        .sorted(Entry.<String,Long>comparingByValue().reversed())
        .limit(n).map(Entry::getKey).toArray(String[]::new);

for (int i = 0; i < result.length; i++) {
   System.out.println(result[i] + " --> " + itemCount.get(result[i]));
}

打印类似的东西

h --> 7
q --> 7
t --> 7
f --> 6
a --> 5
e --> 5
m --> 5
x --> 5
z --> 5
d --> 4

请注意,如果需要,第一个流可以通过流式传输 entrySet() 直接流入第二个流。在这种情况下,您返回数组并且永远看不到实际的地图。

如果您想保留原始地图

如果你想使用你原来的地图和方法,这里有一个带有注释的修改。

public static String[] getMaxListAlt(int n,
        Map<String, Long> itemCount) {
    
    
    // copy entries to a list for sorting.
    List<Entry<String,Long>> entries = new ArrayList<>(itemCount.entrySet());
    
    // sort the entries based on value in  reverse order.
    entries.sort(Entry.<String,Long>comparingByValue().reversed());
    
    // now create the array and just grab the top n items from the sorted
    // entries list.
    String[] maxItems = new String[n];
    for (int i = 0; i < n; i++) {
        maxItems[i] = entries.get(i).getKey();
    }
    
    return maxItems;
}