在 Java 中按键对 HashMap 进行排序

Rashmi Patidar 2023年1月30日 2021年6月30日
  1. 使用 Java 中的 TreeMap 类对键集进行排序
  2. 使用 Java 8 函数对键集进行排序
  3. 理解 Java 中的 Map 初始化流函数
  4. 理解 Java 中的 Map 转换流函数
在 Java 中按键对 HashMap 进行排序

Java 语言中的术语 HashMap 是派生自 Map 接口的集合。该集合或类存在于 java.util 包中,并将数据存储在键值对中。请注意,Map 上不能有两个键。如果插入重复键,则相应键的值将替换为较新的值。

使用 Java 中的 TreeMap 类对键集进行排序

下面的代码块演示了按键对 HashMap 进行排序。

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class HashMapSortByKey {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("2", "Value5");
        map.put("3", "Value1");
        map.put("1", "Value2");
        map.put("4", "Value3");
        map.put("9", "Value4");
        map.put("hi11", "Value6");
        map.put("hi0", "Value7");
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        System.out.println();
        System.out.print("Ordered List: ");
        TreeMap<String, String> map1 = new TreeMap<>(map);
        for (String s : map1.keySet()) {
            System.out.print(" " + s);
        }
    }
}

在上面的代码块中,使用带有 new 关键字的 HashMap 的默认构造函数声明了 map 对象。该语句创建 HashSet 类的实例并将值分配给 Map 接口引用。这些类型是兼容的,因为 HashMap 类在内部实现了 Map 接口。

Map 使用一些键值进行初始化。插入是使用将键绑定到其指定值的 put 方法进行的。如果键已经存在于 Map 中并用指定的值覆盖先前的值,则该方法返回 previous value。当键不在 Map 中时,该函数返回一个 null 值。如果键或值的属性禁止插入值,它会抛出 IllegalArgumentException

现在为了遍历 Map,使用了 for-each 循环。map.keySet 函数返回 Map 中所有键的 Set 格式。keyset 函数在 for-each 循环中获取一个集合,变量可以在该集合上进行迭代;因此,打印键。它将以无序格式打印值,并且没有明确定义的用户获取输出的方式。

为了对 Map 键进行排序,使用了 TreeSet 类。map 变量在实例化时作为 TreeSet 构造函数中的构造函数参数给出。该类实现了 Comparable 接口来对键进行排序。当结果映射 map1 被打印出来时,它会在输出中打印排序后的键。

下面是上面代码块的输出。

输出:

Unordered List:  1 hi11 2 3 4 9 hi0
Ordered List:  1 2 3 4 9 hi0 hi11

使用 Java 8 函数对键集进行排序

Java 8 提供了函数式编程的特权,这有助于在链函数上工作。在下面的程序中,可以看到实例化和初始化发生在一条语句中。而在第一个示例代码中,填充 Map 是一项繁琐的任务。下面给出了在单个语句中了解 Streams 和实例化映射的函数。

Streamsjava.util 包中的一个接口,它提供了一次性处理操作序列的灵活性。Streams 在发射器发射数据的管道中工作;它会根据用户的需要进行过滤、处理、转换等等。

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Stream;

import static java.util.AbstractMap.SimpleEntry;
import static java.util.stream.Collectors.toMap;

public class HashMapSortByKey {
    public static void main(String[] args) {
         Map<String, String> map = Stream.of(new SimpleEntry<>("key6", "value1"),
                new SimpleEntry<>("key12", "value2"),
                new SimpleEntry<>("key9", "value3"))
                .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
        
        System.out.print("Unordered List: ");
        for (String s : map.keySet()) {
            System.out.print(" " + s);
        }
        Map<String, String> mapSortedByKey = map
                .entrySet()
                .stream()
                .sorted(Map.Entry.<String, String>comparingByKey().reversed())
                .collect(Collectors.toMap(Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newValue) -> oldValue,
                        LinkedHashMap::new));

        System.out.println();
        System.out.print("Ordered List: ");
        for (String s1 : mapSortedByKey.keySet()) {
            System.out.print(" " + s1);
        }
    }
}

理解 Java 中的 Map 初始化流函数

首先,Stream 调用 of() 函数,该函数按顺序返回指定的流。该函数创建 SimpleEntry 类的对象以创建键值形式的映射。该类实现了 Entry 接口并具有返回 Map 集合视图的 entrySet 方法。

一旦形成键值条目,就使用 collect 函数将值收集到映射中。它是一个终端函数,意味着在 collect 函数之后不能再调用更多的方法。该函数将流值打包或绑定到所需的数据结构中。

作为参数给出的输入始终是 Collector 引用。toMapCollectors 类中的一个静态函数,它返回一个将流元素绑定到 Map 中的 Collector。该函数采用键 Mapper 和键值 Function 作为其参数。现在,方法引用::运算符意味着调用指定类的函数。

在键映射器中,getKey 函数从填充的 EntrySet 流中提取键。类似地,在键值函数中,调用 getValue 函数以从 EntrySet 流中获取值。

上面代码中的 Collector Function 变量是 Java 中的函数式接口,它们具有一个用于功能的抽象方法。抽象方法的定义在实现它们的类中定义。

理解 Java 中的 Map 转换流函数

在刚刚形成的 map 实例上,调用 entrySet 函数。该函数返回 Map 条目的集合视图,并出现在 Map 界面中。在这些条目上,调用 stream 方法来转换顺序流中的条目。在条目流上,sorted 函数被调用。

它需要一个 Comparator 来比较 Stream 元素。sorted 函数最终返回给定条目的排序流。comparingByKey 函数返回具有默认键顺序的 Map.Entry 比较器。比较器返回一个键集;如果找到的键为空,它会从函数中抛出 NullPointerException

当检索到条目集时,将调用 reversed 函数以反转集合中元素的顺序。最后,通过 Map 流调用 collect 函数。该函数是一个终端运算符,因此,在 collect 函数之后不能调用任何操作。在函数中,调用 toMap 函数以将流转换为 Map。

该函数有四个参数:keyMapper 是一个生成键的函数,valueMapper 是一个创建其值的映射函数,mergeFunction 是一个合并函数的 BinaryOperator,而 mapSupplier 是一个 Supplier 函数,它返回一个新的空 Map,其中插入了结果。最后,生成的控制台输出打印在上面。

输出:

Unordered List:  key12 key6 key9
Ordered List:  key9 key6 key12
Rashmi Patidar avatar Rashmi Patidar avatar

Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.

LinkedIn

相关文章 - Java HashMap