Java SortedMap – Java中的排序图

时间:2020-02-23 14:36:51  来源:igfitidea点击:

Java SortedMap是一个"地图",提供了其键的总排序。

Java SortedMap

Java SortedMap可以根据其键的自然顺序进行排序,也可以在创建地图时通过提供" Comparator"进行排序。

如果在创建SortedMap时未提供任何"比较器"(应该能够接受地图的键),则地图的所有关键元素都必须实现Comparable接口以确保排序。

Java SortedMap构造函数

根据规范,所有通用排序的映射实现类都应提供以下标准构造函数:

  • 一个void(无参数)构造函数:它应该创建一个排序后的映射,并根据其键的自然顺序对其进行排序。

  • 一个参数类型为Comparator的构造函数:它应该创建一个排序映射,其键根据指定的比较器进行排序。

  • 构造函数,其参数类型为Map:应使用提供的map的元素创建一个排序的map,该元素根据其键的自然顺序进行排序。

  • 参数类型为SortedMap的构造函数:它应充当复制构造函数,并使用提供的已排序映射的相同元素和相同顺序创建一个新的已排序映射。

当然,由于接口无法像方法那样指定构造函数,因此无法强制执行这些建议。

Java SortedMap实现

TreeMap是SortedMap的广泛使用的实现。
让我们使用上述不同的构造函数创建其实例:

SortedMap<String, PersonalDetails> personMap = new TreeMap<>();
personMap.put("Dan Brown", new PersonalDetails("Writer", LocalDate.of(1964, 6, 22), "New Hampshire"));
personMap.put("Ayn Rand", new PersonalDetails("Writer", LocalDate.of(1905, 2, 2), "Saint Petersburg"));
personMap.put("Devdutt Pattanaik", new PersonalDetails("Mythologist", LocalDate.of(1970, 12, 11), "Mumbai"));

personMap.keySet().forEach(key -> {
	System.out.println(key + " -> " + personMap.get(key));
});

PersonalDetails实现:

package com.theitroad.sortedmap;

import java.time.LocalDate;

class PersonalDetails {
	String occupation;
	LocalDate dataOfBirth;
	String city;

	public PersonalDetails(String occupation, LocalDate dataOfBirth, String city) {
		this.occupation = occupation;
		this.dataOfBirth = dataOfBirth;
		this.city = city;
	}

	@Override
	public String toString() {
		return this.occupation + ", from " + this.city;
	}
}

它将根据其键的自然顺序打印地图。
在这种情况下,键类型是String,它实现Comparable接口。

代替无参数的构造函数,如果我们在构造函数参数中提供Comparator实现,则输出将具有不同的顺序。
让我们写一个lambda表达式来提供Comparator接口的compareTo实现。
假设我们要按密钥长度的降序对密钥进行排序:

SortedMap<String, PersonalDetails> personMap = new TreeMap<>((s1, s2) -> s2.length() - s1.length());

在这种情况下,输出将如下所示。

Devdutt Pattanaik -> Mythologist, from Mumbai
Dan Brown -> Writer, from New Hampshire
Ayn Rand -> Writer, from Saint Petersburg

现在,我们将通过传递另一个地图对象或者另一个已排序的地图来创建一个已排序的地图。

Map<String, PersonalDetails> map = new HashMap<>();
map.put("Dan Brown", 
new PersonalDetails("Writer", LocalDate.of(1964, 6, 22), "New Hampshire"));
map.put("Ayn Rand",
new PersonalDetails("Writer", LocalDate.of(1905, 2, 2), "Saint Petersburg"));
map.put("Devdutt Pattanaik",
new PersonalDetails("Mythologist", LocalDate.of(1970, 12, 11), "Mumbai"));

SortedMap<String, PersonalDetails> sortedMap = new TreeMap<>(map);
sortedMap.keySet().forEach(key -> {
  System.out.println(key + " -> " + sortedMap.get(key));
});

System.out.println("\nSorted Map constructed using another sorted map:");
SortedMap<String, PersonalDetails> copiedMap = new TreeMap<>(sortedMap);
copiedMap.keySet().forEach(key -> {
  System.out.println(key + " -> " + copiedMap.get(key));
});

输出:

Ayn Rand -> Writer, from Saint Petersburg
Dan Brown -> Writer, from New Hampshire
Devdutt Pattanaik -> Mythologist, from Mumbai

Sorted Map constructed using another sorted map:
Ayn Rand -> Writer, from Saint Petersburg
Dan Brown -> Writer, from New Hampshire
Devdutt Pattanaik -> Mythologist, from Mumbai

Java SortedMap方法

与"地图"相比,提供了几种其他方法来利用订购。
让我们看看提供的每种方法。

  • Comparator比较器():返回用于对映射中的键进行排序的比较器实例。
    如果键是按照其自然顺序排序的,则返回null。

  • Set <Map.Entry> entrySet():返回包含在地图中的一组映射。

  • K firstKey():返回地图中的第一个(最低)键。

  • K lastKey():返回地图中的最后一个(最高)键。

  • Set KeySet():返回一个包含地图所有键的Set。

  • SortedMap headMap(K toKey):返回键小于toKey的地图部分的视图。

  • SortedMap tailMap(K fromKey):返回键大于或者等于fromKey的地图部分的视图。

  • Collection values():返回此映射中包含的值的Collection视图。

请注意,上述方法中返回的Set是实际Set的视图。
在这些视图上所做的更改也会反映在实际数据结构上。

Java SortedMap实现

让我们一一探讨所有这些方法。
我们将通过传递比较器来创建排序后的地图,并且comparator()方法将返回相同的比较器。

SortedMap sortedMap = new TreeMap(Comparator.reverseOrder());
Comparator comparator = sortedMap.comparator();

现在,让我们来看看地图中的映射。
它会为我们提供一个Map.Entry的Set。

SortedMap<String, PersonalDetails> sortedMap = new TreeMap<>(Comparator.reverseOrder());

sortedMap.put("Dan Brown", new PersonalDetails("Writer", LocalDate.of(1964, 6, 22), "New Hampshire"));
sortedMap.put("Ayn Rand", new PersonalDetails("Writer", LocalDate.of(1905, 2, 2), "Saint Petersburg"));
sortedMap.put("Devdutt Pattanaik", new PersonalDetails("Mythologist", LocalDate.of(1970, 12, 11), "Mumbai"));

Set<Map.Entry<String, PersonalDetails>> entrySet = sortedMap.entrySet();

entrySet.forEach(entry -> {
	System.out.println(entry.getKey() + "->" + entry.getValue());
});

遍历entrySet将打印:

Devdutt Pattanaik->Mythologist, from Mumbai
Dan Brown->Writer, from New Hampshire
Ayn Rand->Writer, from Saint Petersburg

keySet()方法将返回键的Set,而values()方法将返回值的Collection(在我们的例子中,值类型为PersonalDetails)。

sortedMap.keySet().forEach(System.out::println);
Collection<PersonalDetails> values = sortedMap.values();
values.forEach(System.out::println);

此外,还有一些方法可用于获取第一个键,最后一个键以及地图中包含小于或者大于等于特定键的键的部分。

System.out.println("Smallest and largest keys of the map:");
System.out.println(sortedMap.firstKey());
System.out.println(sortedMap.lastKey());

System.out.println("Head map containing keys whose values are less than D.");
SortedMap headMap = sortedMap.headMap("D");
headMap.keySet().forEach(System.out::println);

System.out.println("Tail map containing keys whose values are greater than or equal to D:");
SortedMap tailMap = sortedMap.tailMap("D");
tailMap.keySet().forEach(System.out::println);