集合框架复习总结(四)

xiaoxiao2021-02-28  75

之前复习完了List和Set的内容,剩下Map的内容也一起复习了。

Map接口和Collection接口的不同 Map是双列的,Collection是单列的 Map的键唯一,Collection的子体系Set是唯一的 Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

Map是一种把键对象和值对象进行关联的容器         一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样, 一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以 键的唯一性很重要,也是符合集合的性质的。         当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。 Map有两种比较常用的实现:HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用put(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。      一般来说,我们常用的Map子类有HashMap,TreeMap和LinkedHashMap,其与Set的存储结构很相似,LinkedHashMap是底层链表结构,HashMap是运用了哈希算法的,TreeMap是树结构存储,进行了排序。 一、Map基本功能描述 1、添加功能  V put(K key,V value):添加元素。  如果键是第一次存储,就直接存储元素,返回null  如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值 2、删除功能  void clear():移除所有的键值对元素  V remove(Object key):根据键删除键值对元素,并把值返回 3、判断功能  boolean containsKey(Object key):判断集合是否包含指定的键  boolean containsValue(Object value):判断集合是否包含指定的值  boolean isEmpty():判断集合是否为空 4、获取功能  Set<Map.Entry<K,V>> entrySet():  V get(Object key):根据键获取值  Set<K> keySet():获取集合中所有键的集合  Collection<V> values():获取集合中所有值的集合 5、长度功能  int size():返回集合中的键值对的个数

下面举一些例子介绍:

例子1:

public static void main(String[] args) { Map<String,Integer> map = new HashMap<String, Integer>(); //添加元素 map.put("Jack",22); map.put("Marry",23); System.out.println(map); //删除,清空功能 map.remove("Jack"); System.out.println(map); map.clear(); System.out.println(map); } 得到的结果为:

{Jack=22, Marry=23} {Marry=23} {}

例子2:

map.put("Jack",22); map.put("Marry",23); System.out.println(map); //判断集合是否包含键 System.out.println(map.containsKey("Jack")); System.out.println(map.containsKey("Tom")); //判断集合是否包含指定的值 System.out.println(map.containsValue(22)); System.out.println(map.containsValue(25)); 得出的结果为: {Jack=22, Marry=23} true false true false

例子3:

map.put("Jack",22); map.put("Marry",23); System.out.println(map); //判断集合是否为空 System.out.println(map.isEmpty()); map.clear(); System.out.println(map.isEmpty()); 得到的结果为: {Jack=22, Marry=23} false true 例子4:

//添加元素 map.put("Jack",22); map.put("Marry",23); //得到键获取该键的值 System.out.println(map.get("Jack")); System.out.println(map.get("Tom")); //获取集合的长度 System.out.println(map.size());

得到的结果为: 22 null 2 下面重点讲一下遍历的方法: 通常可以使用keyset()方法得到每一个key,然后get(key),得到每一个key对应的值这样来遍历:

map.put("Jack",22); map.put("Marry",23); map.put("Tom", 23); System.out.println(map.keySet()); for (String key : map.keySet()) { System.out.println("我叫" + key + ",今年" + map.get(key) +"岁"); } 得出的结果为: 我叫Jack,今年22岁 我叫Tom,今年23岁 我叫Marry,今年23岁 那么,还有一种方法,是把键和值的键值对封装成一个对象,然后来遍历的: 其方法是使用Map.Entry接口,而Entry接口是Map中的一个子接口,可以单独使用,而还需要获取entrySet()来得到所有键值对,举个例子来解释一下这个方法应该怎么使用: map.put("Jack",22); map.put("Marry",23); map.put("Tom", 23); System.out.println(map.entrySet()); for (Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry + " 我叫" + entry.getKey() + ",年龄为" + entry.getValue()); } 得到的结果为: [Jack=22, Tom=23, Marry=23] Jack=22  我叫Jack,年龄为22 Tom=23  我叫Tom,年龄为23 Marry=23  我叫Marry,年龄为23 其中包含的方法有entrySet()是获取集合中的键值对,getKey()和getvalue()分别是获取键和值。 当然,我们也可以用迭代器进行遍历。 二、Map接口的子类HashMap,TreeMap和LinkedHashMap的简单介绍 1、HashMap 此类不保证映射的顺序,特别是它不保证该顺序恒久不变。基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。另外,HashMap是非线程安全的,也就是说在多线程的环境下,可能会存在问题,而Hashtable是线程安全的。 重点:HashMap和Hashtable的区别 * Hashtable是JDK1.0版本出现的,是线程安全的,效率低,HashMap是JDK1.2版本出现的,是线程不安全的,效率高 * Hashtable不可以存储null键和null值,HashMap可以存储null键和null值 2、LinkedHashMap LinkedHashMap可以保证怎么存就怎么取,其原理和Set有点相似。Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。 3、TreeMap 也是相当于Set的改进,变为键值对形式存储。TreeMap类不仅实现了Map接口,还实现了java.util.SortMap接口,因此集合中的映射关系具有一定的顺序.但是在添加,删除,和定位映射关系上,TreeMap类比HashMap类的性能差一些.TreeMap类实现的Map集合中的映射关系是根据键值对象按一定的顺序排列的.因此不允许键对象是null. 各举一个例子解释一下吧 有一个Person类:

public class Person { public String name; public int age; public Person() { super(); } public Person(String name,int age){ this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public String getName() { return name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 1、HashMap

public static void main(String[] args) { HashMap<Person, String> hm = new HashMap<Person, String>(); hm.put(new Person("Jack",23), "is a doctor"); hm.put(new Person("Marry",24), "is a teacher"); hm.put(new Person("Tom",22), "is a student"); hm.put(new Person("Max",26), "is a worker"); for (Entry<Person, String> en : hm.entrySet()) { System.out.println(en.getKey() + " " +en.getValue()); } } 得到的结果为: Person [name=Max, age=26]  is a worker Person [name=Jack, age=23]  is a doctor Person [name=Marry, age=24]  is a teacher Person [name=Tom, age=22]  is a student 存储是没有顺序的。

2、LinkedHashMap

public static void main(String[] args) { LinkedHashMap<Person, String> lhm = new LinkedHashMap<Person, String>(); lhm.put(new Person("Jack",23), "is a doctor"); lhm.put(new Person("Marry",24), "is a teacher"); lhm.put(new Person("Tom",22), "is a student"); lhm.put(new Person("Max",26), "is a worker"); for (Entry<Person, String> en : lhm.entrySet()) { System.out.println(en.getKey() + " " +en.getValue()); } } 得到的结果为: Person [name=Jack, age=23]  is a doctor Person [name=Marry, age=24]  is a teacher Person [name=Tom, age=22]  is a student Person [name=Max, age=26]  is a worker 怎么存就怎么取。 3、TreeMap

public static void main(String[] args) { TreeMap<Person, String> tm = new TreeMap<Person, String>(new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { int num = p1.getName().compareTo(p2.getName()); return num==0 ? p1.getAge()-p2.getAge() : num; } }); tm.put(new Person("Jack",23), "is a doctor"); tm.put(new Person("Marry",24), "is a teacher"); tm.put(new Person("Tom",22), "is a student"); tm.put(new Person("Max",26), "is a worker"); for (Entry<Person, String> en : tm.entrySet()) { System.out.println(en.getKey() + " " +en.getValue()); }

得到的结果为: Person [name=Jack, age=23]  is a doctor Person [name=Marry, age=24]  is a teacher Person [name=Max, age=26]  is a worker Person [name=Tom, age=22]  is a student 这里是根据比较器,先比较名字,按字典排序,再比较年龄。若再添加一个tm.put(new Person("Jack",22), "is a doctor"),会输出结果: Person [name=Jack, age=22]  is a doctor Person [name=Jack, age=23]  is a doctor Person [name=Marry, age=24]  is a teacher Person [name=Max, age=26]  is a worker Person [name=Tom, age=22]  is a student 好了,到这里集合框架的复习基本回顾完了。

转载请注明原文地址: https://www.6miu.com/read-47135.html

最新回复(0)