首页 > 其他分享 >十一(二)、集合之Map

十一(二)、集合之Map

时间:2022-09-29 15:00:10浏览次数:47  
标签:Map 十一 Object value put key 集合 new newHashMap

一、Map的实现类的结构

--value对的数据 -----类似于高中的函数 y = f(x)

使用Set存储所有的key,key所在的类要重写equals()和hashCode()的方法;(以HashMap为例说的)

HashMap:

  • 作为Map的主要实现类;线程不安全,可以存储null的key和value;
  • HashMap的底层:数组+链表(jdk7及之前)
    数组+链表+红黑树(jdk8)
  • 子类:LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历;

   a、原因是:在原有的hashmap底层结构基础上,添加了一堆指针,指向前一个和后一个元素

   b、对于频繁的遍历操作,此类执行效率更高;

测试代码:

1 @Test
2 public void test() {
3 Map hashMap = new HashMap();
4 hashMap.put(null, null);
5 hashMap.put(123, "AA");
6 hashMap.put(456, "BB");
7 hashMap.put(789, "CC");
8 System.out.println(hashMap);
9
10 LinkedHashMap linkedHashMap = new LinkedHashMap();
11 linkedHashMap.put(null, null);
12 linkedHashMap.put(123, "AA");
13 linkedHashMap.put(456, "BB");
14 linkedHashMap.put(789, "CC");
15 System.out.println(linkedHashMap);
16
17 Hashtable hashtable = new Hashtable();
18 // hashtable.put(null, null);//会报错哦
19
20

这里的

System.out.println(hashMap),无序输出;
System.out.println(linkedHashMap);按插入属性输出

TreeMap:

  • 保证按照添加的key value 对进行排序,实现排序遍历;(需要向tree添加 key-value ,要求key必须是同一个类的对象)
  • 此时使用考虑key的自然排序和定制排序;
  • 底层使用红黑树;

Hashtable:

  • 作为古老的实现类;线程安全;不可以存储null的key和value;
  • 子类:Properties:常用来处理配置文件; key&value 都是Strin

  4.思维导图:

十一(二)、集合之Map_链表

二、Map结构的理解

  1、Map中的key:无序的、不可重复的:

 使用Set存储所有的key,key所在的类要重写equals()和hashCode()的方法;(以HashMap为例说的)

  2、Map中的value:无序的可重复的;

    使用Collection存储所有值;所在类需要重写equals()方法;

-value 构成了一个Entry对象

  4、Map中的Entry:无序的、不可重复的,使用Set存储所有的entry;

 

三、HashMap底层实现原理:(以jdk7说明)

1、实现原理:

1  HashMap map = new HashMap();//在实例化以后,底层创建了长度为16的一维数组Entry[] table;
2
3 ...//可能已经指向过多次put
4
5

  首先:调用key1所在类的hashCode()计算key1的哈希值;此哈希值经过某种算法计算后,得到在Entry数组中的存放位置;

--------情况1

    如果此位置上的数据不为空,(意味着此位置存在或一个或多个数据(以链表形式存在))

      比较key1和已经存在的一个或者多个数据的哈希值

--------情况2

-value2)的哈希值相同,则调用key1所在类的equals方法,

若果返回true,则value1替换

--------情况3

-value1与已经存在指定位置上索引位置上数据以链表形式存储;

 

  在不断添加的过程中,会涉及到扩容问题;默认的扩容方式:当超出临界值且存放位置不为空,扩容为原来容量的2倍,并且将原来的数据复制过来;

 

  jdk8,相较于jdk7;

  1.new HashMap()底层没有创建一个长度为16的数组

  2.jdk8底层的数组是:Node[] 而非Entry[];

  3.首次调用put方法,底层创建长度为16的数组;

  4.jdk7底层结构只有:数组+链表,jdk8中底层结构:数组+链表+红黑树

当数组的某一个索引位置上的元素以及链表形式存在的数据个数》8且当数组的长度>64时,

此索引位置上的说有数据改为红黑树存储;

 2、各常量说明:

  • DEFAULT_INITIAL_CAPACITY:HashMap的默认容量16;
  • DEFAULT_LOAD_FACTOR;HashMap默认的加载因子:0.75
  • 0.7516 = 12
  • TREEIFY_THRESHOLD:桶中链表长度大于该默认值,转换为红黑树:8
  • MIN_TREEIFY_CAPACITY:桶中的node被树话最小的hash表容量:64

四、linkedHashMap的底层实现原理

  • 对于频繁的添加查找元素,可以使用linkedHashMap;
  • 可以按插入顺序输出;

  源码中:没有put 方法,因为继承了HashMap;

1   public class LinkedHashMap<K,V>
2
3 extends HashMap<K,V>
4
5 implements Map<K,V>
6
7

所以这里的put还是HashMap的put方法

linkedHashMap重写了    newNode

1 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
2
3 LinkedHashMap.Entry<K,V> p =
4
5 new LinkedHashMap.Entry<K,V>(hash, key, value, e);
6
7 linkNodeLast(p);
8
9 return p;
10
11

 

1   static class Entry<K,V> extends HashMap.Node<K,V> {
2
3 Entry<K,V> before, after;//这里能够记录添加元素的先后顺序;
4
5 Entry(int hash, K key, V value, Node<K,V> next) {
6
7 super(hash, key, value, next);
8
9 }
10
11

 

五、Map的常用方法:

  1.添加 删除 修改操作

  1. -value(添加、修改)到当前map对象中;
  2. -value对放入当前map中
  3. -value对,并返回value;
  4. void clear();清空当前map中的所有数据

  2、元素查询的操作

  1. Object get(Object key):获取指定key 对应的value
  2. boolean containsKey(Object key),是否包含指定的key
  3. boolean containsValue(Object value):是否包含指定的value;
  4. int size():返回map中key-value对的个数;
  5. boolean isEmpty():判断当前map是否为空;
  6. obj):判断当前map和参数对象obj是否相等

  3.元素操作的方法:

  1. Set keySet();返回左右可以构成的Set集合
  2. Collection values();返回所有values构成的Collection集合;
  3. -value对构成的Set集合;

  总结常用方法:

  • 添加:put(Object key,Object value)
  • 删除:remove(Object key)
  • 修改:put(Object key,Object value)
  • 查询:get(Object key)
  • 遍历:keySet();
  • 长度 size()

-value 的遍历:entrySet()的遍历 or keySet()+get(Object key)来遍历

  key的遍历:keySet()

  value的遍历:values();

这里需要注意的是values()是由Collection存放,如果想取出所有值,建议遍历,将每个ele add到List<Ele>中

常用方法测试:

1 /**
2 *1.添加 删除 修改操作
3 * Object put(Object key,Object value);将指定的key-value(添加、修改)到当前map对象中;
4 * void putAll(Map m),将m中所有的 key-value对放入当前map中
5 * Object remove(Object key),移除指定的key-value对,并返回value;
6 * void clear();清空当前map中的所有数据
7 * 2、元素查询的操作
8 * Object get(Object key):获取指定key 对应的value
9 * boolean containsKey(Object key),是否包含指定的key
10 * boolean containsValue(Object value):是否包含指定的value;
11 * int size():返回map中key-value对的个数;
12 * boolean isEmpty():判断当前map是否为空;
13 * boolean equals(Object obj):判断当前map和参数对象obj是否相等;
14 * Set keySet();返回左右可以构成的Set集合
15 * Collection values();返回所有values构成的Collection集合;
16 * Set entrySet():随会所有key-value对构成的Set集合;
17 *
18 */
19 @Test
20 public void test1() {
21 Map hashMap = new HashMap();
22 //Object put(Object key,Object value)来添加元素
23 hashMap.put(null, null);
24 hashMap.put(123, "AA");
25 hashMap.put(456, "BB");
26 hashMap.put(789, "CC");
27 System.out.println("hashMap:"+hashMap);
28 // void putAll(Map m),将m中所有的 key-value对放入当前map中
29 Map newHashMap = new HashMap();
30 newHashMap.putAll(hashMap);
31 System.out.println("newHashMap:"+newHashMap);//所有hashMap中的数据放入了newHashMap中;
32
33 System.out.println("newHashMap的equals方法:"+newHashMap.equals(hashMap));
34
35 hashMap.remove(123);
36 System.out.println("hashMap的remove方法:"+hashMap);
37
38 hashMap.clear();//
39 System.out.println("hashMap的clear方法:"+hashMap);//{},而不是null
40
41 Object obj = newHashMap.get(123);
42 System.out.println("newHashMap的get方法:"+obj);
43
44 boolean flag1 = newHashMap.containsKey("AA");
45 System.out.println("newHashMap的containsKey方法:"+flag1);
46
47 boolean flag2 = newHashMap.containsValue("AA");
48 System.out.println("newHashMap的containsValue方法:"+flag2);
49
50 System.out.println("newHashMap的size方法:"+newHashMap.size());
51
52 System.out.println("newHashMap的isEmpty方法:"+newHashMap.isEmpty());//就是判断size()是否为0
53
54 System.out.println("newHashMap的keySet方法:"+newHashMap.keySet());
55 //遍历所有的key
56 Set keySet = newHashMap.keySet();
57 Iterator iterator = keySet.iterator();
58 while(iterator.hasNext()) {
59 System.out.println("遍历所有的key:"+iterator.next());
60 }
61
62 System.out.println("newHashMap的values方法:"+newHashMap.values());
63 //遍历所有的values
64 Collection values = newHashMap.values();
65 Iterator iterator2 = values.iterator();
66 while(iterator2.hasNext()) {
67 System.out.println("遍历所有的values:"+iterator2.next());
68 }
69
70 System.out.println("newHashMap的entrySet方法:"+newHashMap.entrySet());
71 //遍历所有的entrySet
72 Set entrySet = newHashMap.entrySet();
73 Iterator iterator3 = entrySet.iterator();
74 while(iterator3.hasNext()) {
75 Entry entry = (Entry) iterator3.next();
76 System.out.println(entry.getKey()+"--->"+entry.getValue());//输出键值对;
77 }
78
79 //输出键值对
80 Set keySet1 = newHashMap.keySet();
81 Iterator iterator4 = keySet.iterator();
82 while(iterator4.hasNext()) {
83 Object key = iterator4.next();
84 System.out.println(key+"--->"+newHashMap.get(key));//输出键值对;
85 }
86
87

 

六、TreeMap中的排序:

  1. -value ,要求key必须是同一个类的对象
  2. 因为要按照key 排序(自然排序、定制排序)

测试代码:

1 //定制排序
2 @Test
3 public void test2() {
4 Comparator com = new Comparator<Person>() {
5
6 @Override
7 public int compare(Person o1, Person o2) {
8 if(o1.getAge()-o2.getAge()>=0) {
9 return 1;
10 }
11 return -1;
12 }
13 };
14 TreeMap treeMap = new TreeMap(com);
15 treeMap.put( new Person("joy",30), new Object());
16 treeMap.put(new Person("tom",31), new Object());
17 treeMap.put(new Person("lucy",18), new Object());
18 treeMap.comparator();
19 Iterator iterator = treeMap.keySet().iterator();
20 while(iterator.hasNext()) {
21 System.out.println(iterator.next());
22 }
23
24 }
25
26 //自然排序;
27 @Test
28 public void test3() {
29 TreeMap treeMap = new TreeMap();
30 treeMap.put( new Person("joy",30), new Object());
31 treeMap.put(new Person("tom",31), new Object());
32 treeMap.put(new Person("lucy",18), new Object());
33 Iterator iterator = treeMap.keySet().iterator();
34 while(iterator.hasNext()) {
35 System.out.println(iterator.next());
36 }
37
38

附:

1 package collection;
2
3 public class Person implements Comparable {
4
5 private String name;
6 private int age;
7 public String getName() {
8 return name;
9 }
10 public void setName(String name) {
11 this.name = name;
12 }
13 public int getAge() {
14 return age;
15 }
16 public void setAge(int age) {
17 this.age = age;
18 }
19 public Person(String name, int age) {
20 super();
21 this.name = name;
22 this.age = age;
23 }
24 public Person() {
25 super();
26 }
27 @Override
28 public String toString() {
29 return "Person [name=" + name + ", age=" + age + "]";
30 }
31 @Override
32 public int hashCode() {
33 final int prime = 31;//这里使用31为了减少冲突、提高算法效率
34 int result = 1;
35 result = prime * result + age;
36 result = prime * result + ((name == null) ? 0 : name.hashCode());
37 return result;
38 }
39 @Override
40 public boolean equals(Object obj) {
41 if (this == obj)
42 return true;
43 if (obj == null)
44 return false;
45 if (getClass() != obj.getClass())
46 return false;
47 Person other = (Person) obj;
48 if (age != other.age)
49 return false;
50 if (name == null) {
51 if (other.name != null)
52 return false;
53 } else if (!name.equals(other.name))
54 return false;
55 return true;
56 }
57 @Override
58 public int compareTo(Object o) {
59 Person person = (Person)o;
60 if(this.age>person.age) {
61 return -1;
62 }else {
63 return 1;
64 }
65
66 }
67
68
69

View Code

七、Properties

Hashtable的子类,该对象用于处理属性文件

  • 由于属性文件里的key、value都是字符串类型,所以Properties中里的key和value都是字符串类型
  • 存取数据时,建议使用 setProperty(String key,String value)和 getProperty(String key)

 测试代码:

1 //Properties用来处理配置文件,key和value都是字符串类型
2 @Test
3 public void test4() throws Exception {
4 Properties prop = new Properties();
5 FileInputStream fis = new FileInputStream(new File("testproperties.properties"));//文件:testproperties.properties
6 prop.load(fis);//加载对应流文件
7 String name = prop.getProperty("name");
8 String value = prop.getProperty("password");
9 System.out.println("name:"+name);
10 System.out.println("value:"+value);
11
1 name=tom
2

View Code

 

我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。



标签:Map,十一,Object,value,put,key,集合,new,newHashMap
From: https://blog.51cto.com/u_10632206/5722963

相关文章

  • HashMap源码,看我这篇就够了
    HashMap源码深度剖析*HashMap底层数据结构(为什么引入红黑树、存储数据的过程、哈希碰撞相关问题)*HashMap成员变量(初始化容量是多少、负载因子、数组长度为什么是2......
  • Springboot自定义工具类中调用mapper或者service接口方式
    1、该类使用@Component注解2、添加一个本类类型的静态字段3、创建一个初始化方法,贴上@PostConstruct标签,用于注入bean4、创建方法调用mapper或service接口5、最后直接......
  • Golang Redis有序集合(sorted set)
    Redis有序集合(sortedset)和集合一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double类型的分数,这个分数主要用于集合元素排序。引用git......
  • mapboxgl加载tiff
    缘起近期在项目中遇到这么一个需求,需要在地图上展示一组格网数据,格网大小为2m*2m,地图api用的mapboxgl。起初拿到这个需要感觉很easy,在地图上添加一个fill图层就好啦。把格......
  • [答疑]想表示消息返回值为Customer集合
    道奈特(240***10)14:34:55EA中序列图。我想表示消息返回值为Customer集合。目前只有一个Customer实体类,我需要另外新建一个CustomerList类吗?潘加宇(3504847)17:01:26不......
  • mapstruct 使用注意
    <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId>......
  • WPF 通过 GifBitmapDecoder 调用 WIC 解析 Gif 和进行动画播放的简单方法
    本文告诉大家如何在WPF里,通过GifBitmapDecoder调用WIC层来解析GIF图片,然后采用动画的方式进行播放在上一篇博客告诉大家,可以通过GifBitmapDecoder调用WIC层解......
  • sqlmap绕过token保护
    1、演示页面<?phpsession_start();if(isset($_SESSION['token'])&&isset($_POST['username'])){if(empty($_POST['token'])||$_POST['token']!=$_SESSION['token']){......
  • 20201220蔡笃俊《信息安全系统设计与实现》第十一章学习笔记
    ext2文件系统一、任务内容自学教材第11章,提交学习笔记(10分)知识点归纳以及自己最有收获的内容(3分)问题与解决思路(2分)实践内容与截图,代码链接(3分)...(知识的结构化,知识......
  • ArcMap中如何删除属性域
    如果域被要素类占用,那么不能直接删除域,需要解除字段和域的关联,才能删除域。解除关联可以使用GP工具RemoveDomainFromField,工具在Toolboxes\SystemToolboxes\DataManage......