在本文中,我们将讨论Java中Map.of()和new HashMap<>()的用法,它们之间的区别,以及使用Map.of()的好处。
Java是一种流行的编程语言,用于开发广泛的应用程序,包括web、移动和桌面应用程序。它为开发人员在他们的程序中使用提供了许多有用的数据结构,其中之一就是Map数据格式。这Map接口用于以键值对的形式存储数据,这使得它成为许多应用程序的基本数据结构。
在本文中,我们将讨论Map.of()和新的HashMap<>()在Java中,它们之间的区别,以及使用Map.of().
什么是Map.of()?
Map.of()是Java 9中引入的一种方法,它允许开发人员创建最多有10个键值对的不可变映射。
它提供了一种方便而简洁的创建地图的方法,使得创建小地图变得更加容易,而无需编写大量代码。Map.of()是对以前使用的构造函数创建小地图的方法的改进HashMap类,这可能很麻烦而且冗长。
什么是New HashMap<>()?
新的HashMap<>() 是由提供的构造函数HashMap类,它允许开发人员创建HashMap。它用于创建可变映射,这意味着可以通过添加、删除或更新键-值对来修改映射。
这是在Java中创建Map的常用方法,尤其是在处理大型数据集时。
基准测试Map.of()和HashMap<>()
比较基准的表现Map.of()和new HashMap<>()在Java中,我们可以使用基准测试工具来测量在使用这些方法创建的Map上执行各种操作所花费的时间。在我们的基准测试中,我们将测量从Map中获取值所花费的时间以及将值插入到Map中所花费的时间。
值得注意的是,我们的基准测试仅限于一小组数据,比如十项。对于更大的数据集或更复杂的用例,结果可能会有所不同。
package ca.bazlur;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 20, time = 1)
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@OperationsPerInvocation
public class MapBenchmark {
private static final int SIZE = 10;
private Map mapOf;
private Map hashMap;
@Setup
public void setup() {
mapOf = Map.of(
0, "value0",
1, "value1",
2, "value2",
3, "value3",
4, "value4",
5, "value5",
6, "value6",
7, "value7",
8, "value8",
9, "value9"
);
hashMap = new HashMap<>();
hashMap.put(0, "value0");
hashMap.put(1, "value1");
hashMap.put(2, "value2");
hashMap.put(3, "value3");
hashMap.put(4, "value4");
hashMap.put(5, "value5");
hashMap.put(6, "value6");
hashMap.put(7, "value7");
hashMap.put(8, "value8");
hashMap.put(9, "value9");
}
@Benchmark
public void testMapOf(Blackhole blackhole) {
Map map = Map.of(
0, "value0",
1, "value1",
2, "value2",
3, "value3",
4, "value4",
5, "value5",
6, "value6",
7, "value7",
8, "value8",
9, "value9"
);
blackhole.consume(map);
}
@Benchmark
public void testHashMap(Blackhole blackhole) {
Map hashMap = new HashMap<>();
hashMap.put(0, "value0");
hashMap.put(1, "value1");
hashMap.put(2, "value2");
hashMap.put(3, "value3");
hashMap.put(4, "value4");
hashMap.put(5, "value5");
hashMap.put(6, "value6");
hashMap.put(7, "value7");
hashMap.put(8, "value8");
hashMap.put(9, "value9");
blackhole.consume(hashMap);
}
@Benchmark
public void testGetMapOf() {
for (int i = 0; i < 10; i++) {
mapOf.get(i);
}
}
@Benchmark
public void testGetHashMap() {
for (int i = 0; i < SIZE; i++) {
hashMap.get(i);
}
}
}
Benchmark Mode Cnt Score Error Units
MapBenchmark.testGetHashMap avgt 20 14.999 ± 0.433 ns/op
MapBenchmark.testGetMapOf avgt 20 16.327 ± 0.119 ns/op
MapBenchmark.testHashMap avgt 20 84.920 ± 1.737 ns/op
MapBenchmark.testMapOf avgt 20 83.290 ± 0.471 ns/op
这些是比较使用new HashMap<>()和Map.of()在Java里。基准测试是用有限的小数据集进行的(例如,10).
这些结果表明HashMap速度稍快get与不可变操作相比Map使用创建的Map.of()。然而,创建一个不可变的Map使用Map.of()仍然比创建一个HashMap.
请注意,基于您的JDK发行版和计算机,当您尝试时,基准测试结果可能会略有不同。然而,在大多数情况下,结果应该是一致的。运行您自己的基准来确保您为您的特定用例做出正确的选择总是一个好主意。
此外,请记住,微基准应该有所保留,而不是作为决策的唯一因素。还应该考虑其他因素,如内存使用、线程安全和代码可读性。
源代码可以在在GitHub上.
在我看来,性能上的微小差异在大多数情况下可能并不重要。在做出选择时,考虑其他方面是很重要的,比如特定的用例,它有多简洁,组织良好的代码,以及首选的特性(例如,可变或不可变的性质)HashMap和Map.of()。对于简单的场景,Map.of()在简单和简洁方面可能仍然占优势。
让我们来看看使用Map.of().
使用Map.of()的好处
使用有几个好处Map.of()在新的HashMap<>()在Java中:
- 简洁: Map.of()提供了一种在Java中创建小Map的简洁而方便的方法。这使得代码可读性更好,也更容易维护。
- 不变: Map.of()创建不可变的映射,这意味着一旦映射被创建,就不能被修改。这为存储在Map中的数据提供了一定程度的安全性。
- 类型安全: Map.of()为映射的键和值提供类型安全,这有助于防止在使用new HashMap<>().
结论
Map.of()是Java 9中引入的一种强大而有用的方法,它提供了一种更简洁的方式来用Java创建小Map,并增加了不变性和类型安全等好处。
我们的基准测试显示Map.of()和新的HashMap<>()因为小Map是接近的,具有重叠的误差线,这使得很难仅基于该数据明确地得出一种方法明显快于另一种方法的结论。
使用的好处Map.of()包括其简洁性、不变性和类型安全性。尽管根据所提供的基准测试结果,性能差异可能并不显著,但Map.of()让它成为一个吸引人的选择。
开发人员应该考虑使用Map.of()当用Java创建Map来利用这些好处时。
本文暂时没有评论,来添加一个吧(●'◡'●)