【从零开始的Java秃头之旅】02

从零开始的Java秃头之旅之Java篇

今天主要学习了一下Map集合的一些方法,以及包括HashMap、LinkedHashMap、Hashtable在内的集合。

首先说下Map集合的特点:
1.Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)。
2.Map集合中的元素,key和value的数据类型可以相同,也可以不相同。
3.Map集合中的元素,key是不允许重复的,value是可以重复的。
4.Map集合中的元素,key和value是一一对应的。
java.util.HashMap集合 implements Map接口

其次HashMap集合的特点:
1.HashMap集合底层是哈希表:查询速度特别快。
(JDK1.8之前:数组+单向链表 组成;JDK1.8之后:数组+单向链表/红黑树(链表的长度超过8),提高查询的速度)
2.HashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致。

最后来说一下HashMap的子类也就是LinkedHashMap的特点:
(java.util.LinkedHashMap集合 extends HashMap集合)
LinkedHashMap的特点:
1.LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)。
2.LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的。(这也是和HashMap最主要的区别,个人感觉)

Map集合的主要方法

public V put(K key,V value):  把指定的键与指定的值添加到Map集合中
public V remove(Object key):把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值.
public V get(Object key)根据指定的键,在Map集合中获取对应的值.
boolean containsKey(Object key) 判断集合中是否包含指定的键,包含返回true,不包含返回false

这几个方法都较为简单,不做赘述。
接下来就要强调一下Map集合的两种遍历方式
1、通过KeySet方式(键找值)。
2、使用Entry对象遍历。

这边上第一种方式的代码:

public class Demo02KeySet {
		public static void main(String[] args){
			Map map = new HashMap<>();
			map.put("赵丽颖", 168);
			map.put("杨颖", 165);
			map.put("林志玲", 178);
			
			//1.使用Map集合中的方法keySet(),把集合所有的key取出来,存储到一个Set集合中
			Set set = map.keySet();
			
			//2.遍历Set集合,获取Map集合中的每一个key
			//使用迭代器遍历Set集合
			Iterator it = set.iterator();
			while(it.hasNext()){
				String key = it.next();
				//3.通过map集合中的方法get(key),通过key找到value
			    Integer value = map.get(key);
			    System.out.println(key+"="+value);
			}
			System.out.println("==========");
			for(String key:set){
			    Integer value = map.get(key);
			    System.out.println(key+"="+value);
			}
		}
}

其中又分别用了两种遍历方式(迭代器和增强for循环)。其中最主要的还是Map集合的keySet()方法。

Set keySet() 返回此映射中包含的键的Set视图.

接下来看第二种方式的(entry)代码:

public class Demo03EntrySet {
		public static void main(String[] args){
			//创建Map集合对象
			Map map = new HashMap<>();
			map.put("赵丽颖", 168);
			map.put("杨颖", 165);
			map.put("林志玲", 178);
			
			//1.使用Map集合中的方法entrySet(),
			把Map集合中多个Entry对象取出来,存储到一个Set集合中
			Set> set = map.entrySet();
			
			//2.遍历Set集合,获取每一个Entry集合
			//使用迭代器遍历Set集合
			Iterator> it = set.iterator();
			while(it.hasNext()){
				Map.Entry entry = it.next();
				//3.使用Entry对象中的方法getKey()和getValue()获取键与值
				String key = entry.getKey();
				Integer value = entry.getValue();
				System.out.println(key+"+"+value);
			}
			System.out.println("==========");
			for(Map.Entry entry:set){
				String key = entry.getKey();
				Integer value = entry.getValue();
				System.out.println(key+"+"+value);
			}
		}
}

这个方法的原理是将Map集合中的key和value建立一个entry关系,类似于结婚证。
和上一个方法一样,其中最重要的还是entrySet()方法了。

	Set> entrySet() 
	返回此映射中包含的映射关系的Set视图。		

不过个人感觉这个代码写起来太复杂了,不如第一个简单便捷。

接下来就学习了HashMap和LinkedHashMap集合。
我们知道HashMap是双列集合,包含有key值和value值。我们分别将key和value定义为自定义Person类。下面看代码:

public class Demo01HashMapSavePerson {
	public static void main(String[] args){
//		show01();
		show02();
	}
	
	/*
	 		HashMap存储自定义类型键值
	 		key:String类型
	 				String类重写hashCode方法和equals方法,可以保证key唯一
	 		value:Person类型
	 				value可以重复(同名同年龄的人视为同一人)
	 */
	private static void show01(){
		//创建HashMap集合
		HashMap map = new HashMap<>();
		map.put("北京", new Person("张三",18));
		map.put("上海", new Person("李四",19));
		map.put("广州", new Person("王五",20));
		map.put("北京", new Person("赵六",18));
		
		//使用keyset+增强for循环遍历输出HashMap集合
		Set set = map.keySet();
		for(String key:set){
			Person value = map.get(key);
			System.out.println(key+"-->"+value);
		}
	}
	/*
	 		HashMap存储自定义类型键值
	 		key:Person类型
	 					Person类就必须重写hashCode方法和equals方法,可以保证key唯一
			value:String类型
					可以重复
	 */
	private static void show02(){
		HashMap map = new HashMap<>();
		map.put(new Person("女王",18), "英国");
		map.put(new Person("秦始皇",18), "秦国");
		map.put(new Person("普京",30), "俄罗斯");
		map.put(new Person("女王",18), "毛里求斯");
		//使用entrySet和增强for循环遍历Map集合
		Set> set = map.entrySet();
		for(Map.Entry entry:set){
			Person key = entry.getKey();
			String value = entry.getValue();
			System.out.println(key+"-->"+value);
		}
	}
}

这边就有一个问题了,Map集合一定保证key是唯一的,作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一。
那么为什么重写了equals方法就必须重写hashCode方法呢?
答:假如我们需要实现类似 Person这种基于对象内容来判断两个对象是否相等的情况时,我们肯定会在对象中重写 equals 方法,在平时的使用中,我们只要重写 equals 方法即可。

但是如果涉及需要将对象放入类似 HashMap、HashSet 类似的集合中时,他们底层的原理都是,先判断传入的键的 hash 值是否相同,如果不同则直接放入集合中,如果相同,则在进行 equals 判断,如果 equals 也是相同,那么后来传入的键会将前面的键覆盖。

对于 String、Integer 这类的包装类,底层已经重写了 hashCode 方法,即都是唯一的。但是,如果我们自己声明了类似 Person 这样的对象,在没有重写 hashCode 方法的情况下,在将对象传入集合类的过程中,会首先计算你传入值的 hash 值,因为对象没有重写 hashCode 方法,因此你两次放入的内容相同的对象还是会被当作两个不同的对象。此时,唯一的解决方法便是,在对象中重写 hashCode 方法。

参考:
https://blog.csdn.net/babycan5/article/details/88586821

你可能感兴趣的:(【从零开始的Java秃头之旅】02)