ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## [映射Map](https://lingcoder.gitee.io/onjava8/#/book/12-Collections?id=%e6%98%a0%e5%b0%84map) 将对象映射到其他对象的能力是解决编程问题的有效方法。例如,考虑一个程序,它被用来检查 Java 的**Random**类的随机性。理想情况下,**Random**会产生完美的数字分布,但为了测试这一点,则需要生成大量的随机数,并计算落在各种范围内的数字个数。**Map**可以很容易地解决这个问题。在本例中,键是**Random**生成的数字,而值是该数字出现的次数: ~~~ // collections/Statistics.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Simple demonstration of HashMap import java.util.*; public class Statistics { public static void main(String[] args) { Random rand = new Random(47); Map<Integer, Integer> m = new HashMap<>(); for(int i = 0; i < 10000; i++) { // Produce a number between 0 and 20: int r = rand.nextInt(20); Integer freq = m.get(r); // [1] m.put(r, freq == null ? 1 : freq + 1); } System.out.println(m); } } /* Output: {0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519, 7=471, 8=468, 9=549, 10=513, 11=531, 12=521, 13=506, 14=477, 15=497, 16=533, 17=509, 18=478, 19=464} */ ~~~ * **\[1\]**自动包装机制将随机生成的**int**转换为可以与**HashMap**一起使用的**Integer**引用(不能使用基本类型的集合)。如果键不在集合中,则`get()`返回**null**(这意味着该数字第一次出现)。否则,`get()`会为键生成与之关联的**Integer**值,然后该值被递增(自动包装机制再次简化了表达式,但实际上确实发生了对**Integer**的装箱和拆箱)。 接下来的示例将使用一个**String**描述来查找**Pet**对象。它还展示了通过使用`containsKey()`和`containsValue()`方法去测试一个**Map**,以查看它是否包含某个键或某个值: ~~~ // collections/PetMap.java import typeinfo.pets.*; import java.util.*; public class PetMap { public static void main(String[] args) { Map<String, Pet> petMap = new HashMap<>(); petMap.put("My Cat", new Cat("Molly")); petMap.put("My Dog", new Dog("Ginger")); petMap.put("My Hamster", new Hamster("Bosco")); System.out.println(petMap); Pet dog = petMap.get("My Dog"); System.out.println(dog); System.out.println(petMap.containsKey("My Dog")); System.out.println(petMap.containsValue(dog)); } } /* Output: {My Dog=Dog Ginger, My Cat=Cat Molly, My Hamster=Hamster Bosco} Dog Ginger true true */ ~~~ **Map**与数组和其他的**Collection**一样,可以轻松地扩展到多个维度,只需要创建一个值为**Map**的**Map**(这些**Map**的值可以是其他集合,甚至是其他**Map**)。因此,能够很容易地将集合组合起来以快速生成强大的数据结构。例如,假设你正在追踪有多个宠物的人,只需要一个**Map>**即可: ~~~ // collections/MapOfList.java // {java collections.MapOfList} package collections; import typeinfo.pets.*; import java.util.*; public class MapOfList { public static final Map<Person, List< ? extends Pet>> petPeople = new HashMap<>(); static { petPeople.put(new Person("Dawn"), Arrays.asList( new Cymric("Molly"), new Mutt("Spot"))); petPeople.put(new Person("Kate"), Arrays.asList(new Cat("Shackleton"), new Cat("Elsie May"), new Dog("Margrett"))); petPeople.put(new Person("Marilyn"), Arrays.asList( new Pug("Louie aka Louis Snorkelstein Dupree"), new Cat("Stanford"), new Cat("Pinkola"))); petPeople.put(new Person("Luke"), Arrays.asList( new Rat("Fuzzy"), new Rat("Fizzy"))); petPeople.put(new Person("Isaac"), Arrays.asList(new Rat("Freckly"))); } public static void main(String[] args) { System.out.println("People: " + petPeople.keySet()); System.out.println("Pets: " + petPeople.values()); for(Person person : petPeople.keySet()) { System.out.println(person + " has:"); for(Pet pet : petPeople.get(person)) System.out.println(" " + pet); } } } /* Output: People: [Person Dawn, Person Kate, Person Isaac, Person Marilyn, Person Luke] Pets: [[Cymric Molly, Mutt Spot], [Cat Shackleton, Cat Elsie May, Dog Margrett], [Rat Freckly], [Pug Louie aka Louis Snorkelstein Dupree, Cat Stanford, Cat Pinkola], [Rat Fuzzy, Rat Fizzy]] Person Dawn has: Cymric Molly Mutt Spot Person Kate has: Cat Shackleton Cat Elsie May Dog Margrett Person Isaac has: Rat Freckly Person Marilyn has: Pug Louie aka Louis Snorkelstein Dupree Cat Stanford Cat Pinkola Person Luke has: Rat Fuzzy Rat Fizzy */ ~~~ **Map**可以返回由其键组成的**Set**,由其值组成的**Collection**,或者其键值对的**Set**。`keySet()`方法生成由在**petPeople**中的所有键组成的**Set**,它在*for-in*语句中被用来遍历该**Map**。