Map的子集合

1、HashMap

HashMap集合本身基于哈希表,它可以保证键的唯一性(Map都是针对键有效),基本格式:HashMap<Key,Value>,其中Key和Value可以是String,Integer等任意类型,包括自定义类型。

下来我们通过实际的例子分别看一下基本类型和自定义类型的情况。

基本类型:

public class HashMapDemo2 {
	
	public static void main(String[] args) {
		//创建集合对象
		HashMap<Integer, String> map = new HashMap<Integer,String>() ;
		
		//添加元素
		map.put(27, "高圆圆") ;
		map.put(29, "西施") ;
		map.put(28, "唐嫣") ;
		map.put(27, "文章") ;
		
		//遍历
		Set<Integer> set = map.keySet();
		for(Integer key :set) {
			String value = map.get(key) ;
			System.out.println(key+"---"+value);
		}
	}
}

自定义类型:

HashMap<Student,String> 键:是一种自定义类型

Student:学生:年龄和姓名
String:朝代 
如果对象的成员变量值一样,认为同一个人.由于Student是我们自定义的类,所以必须在Student类中重写hashCode()方法和equals()方法,这样才能在成员变量值一样时,认为是同一个人。
HashMap底层哈希表

哈希表:依赖于两个方法  hashCode() ,equals()方法

Student类:

public class Student {
	
	private String name ;
	private int age ;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	
	// 重写hashCode()和equals()方法
	@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 (!(obj instanceof Student))
			return false;
		Student other = (Student) 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 class HashMapDemo4 {
	
	public static void main(String[] args) {
		
		//创建集合对象
		HashMap<Student, String>  map = new HashMap<Student,String>() ;
		
		//创建学生对象
		Student s1 = new Student("西施", 27) ;
		Student s2 = new Student("杨贵妃", 35) ;
		Student s3 = new Student("王昭君", 30) ;
		Student s4 = new Student("貂蝉",28) ;
		Student s5 = new Student("西施", 27) ;
	
		
		//添加元素
		map.put(s1, "元朝") ;
		map.put(s2, "宋朝") ;
		map.put(s3, "唐朝") ;
		map.put(s4, "清朝") ;
		map.put(s5, "金") ;
		
		//遍历
		Set<Student> set = map.keySet() ;
		for(Student s :set) {
			String value = map.get(s) ;
			System.out.println(s.getName()+"---"+s.getAge()+"---"+value);
		}
	}
}

2、LinkedHashMap

LinkedHashMap<K,V> :是Map接口基于哈希表和链接列表实现的
        哈希表保证键的唯一性

        链接列表保证元素有序性(存储和取出一致)

public class LinkedHashMapDemo {

	public static void main(String[] args) {
		LinkedHashMap<String, String> map = new LinkedHashMap<String,String>() ;
		
		//添加元素
		map.put("it001", "hello");
		map.put("it002", "mysql");
		map.put("it003", "world");
		map.put("it004", "javaweb");
		map.put("it001", "javaee");
		
		Set<String> set = map.keySet() ;
		for(String key :set) {
			String value = map.get(key) ;
			System.out.println(key+"----"+value);
		}
	}
}

3、TreeMap

TreeMap基于红黑树结构的Map接口的实现,所以TreeMap可以对集合进行排序。

1)TreeMap存储基本类型:

public class TreeMapDemo {

	public static void main(String[] args) {
		
		TreeMap<String,String> tm = new TreeMap<String,String>();
		
		tm.put("java", "爪哇");
		tm.put("hello", "哈喽");
		tm.put("abc", "字母");
		tm.put("cat", "猫");
		tm.put("club", "俱乐部");
		tm.put("java", "爪哇2");
		
		Set<String> str = tm.keySet();
		
		for(String key:str) {
			String value = tm.get(key);
			System.out.println(key+"---"+value);
		}
	}
}

运行结果:

abc---字母
cat---猫
club---俱乐部
hello---哈喽

java---爪哇2

可以看出,TreeMap集合已经对字符串进行了排序。

2)TreeMap存储自定义类型,TreeMap<Student,String>,对集合进行排序,主要条件:年龄从小到大

public class TreeMapDemo2 {
	
	public static void main(String[] args) {
		
		//创建一个TreeMap集合,使用比较器排序的方式
		//匿名内部类的方式
		TreeMap<Student, String>  tm = new TreeMap<Student,String>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
				
				//主要条件:年龄从小到大
				int num =s1.getAge() -s2.getAge() ;
				//年龄相同,不一定姓名一样
				int num2 = num ==0 ? s1.getName().compareTo(s2.getName()): num ;
				return num2 ;
			}
			
		} );
		
		//创建学生对象
		Student s1 =  new Student("唐伯虎", 28) ;
		Student s2 =  new Student("杜甫", 35) ;
		Student s3 =  new Student("李白", 40) ;
		Student s4 =  new Student("李清照", 32) ;
		Student s5 =  new Student("唐伯虎", 28) ;
		Student s6 =  new Student("苏轼", 35) ;
		
		//添加到集合中
		tm.put(s1, "宋代") ;
		tm.put(s2, "唐代") ;
		tm.put(s3, "唐代") ;
		tm.put(s4, "宋代") ;
		tm.put(s5, "清代") ;
		tm.put(s6, "清代") ;
		
		
		//遍历
		Set<Student> set = tm.keySet() ;
		for(Student key :set) {
			String value = tm.get(key) ;
			System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
		}
	}
}
面试题:
HashMap集合和Hashtable的区别?
共同点:都是map接口的实现类,都是基于哈希表的实现类
HashMap集合线程不安全的类,不同步,执行效率高(允许键和值是null的)
Hashtable集合线程安全的类,同步,执行效率低(不允许有null键和null值) 

我们目前学习过的线程安全的类:
StringBuffer     :字符串缓冲区
Vector         :List集合

Hashtable        :Map集合的

public class HashtableDemo {

	public static void main(String[] args) {
		
		//创建HashMap集合对象
		HashMap<String, String> hm = new HashMap<String,String>() ;
		Hashtable<String, String> ht = new Hashtable<String,String>() ;
		
		//添加元素
		hm.put("hello", null);
		hm.put(null, "world") ;
		
		//ht.put("hello", null);//NullPointerException
		//ht.put(null, "world");//NullPointerException
		
		
		System.out.println(hm);
		//System.out.println(ht);//输出的集合元素的字符串表现形式
	}
}


练习:

现有如下需求:

字符串:比如: aaaaabbbbcccddddee   ,最终控制台要出现的结果:a(5)b(4)c(3)d(3)e(2)
 
思路:
1)改进:键盘录入一个字符串
2)创建一个HashMap集合key:Character,Value:Integer
3)将录入的字符串转换成字符数组
4)遍历可以获取每一个字符
5)将元素添加到对应的HashMap集合中
使用的put(key,value): 通过判断值是否null ,如果是null表示第一次存储
集合对象.put(ch,1) ;
否则,不是null
Integer那个值++;
集合对象.put(ch,变量Integer值)  ;

6)遍历HashMap集合即可

public class Test {
	
	public static void main(String[] args) {
		
		//创建键盘录入对象
		Scanner sc = new Scanner(System.in);
		
		//接收数据
		System.out.println("请输入一个字符串:");
		String line = sc.nextLine() ;
		
		//创建一个HashMap集合来存储对应的字符和值
		HashMap<Character, Integer> hm = new HashMap<Character,Integer>() ;
		
		//将字符串转换成字符串
		char[] chs = line.toCharArray() ;
		
		//遍历字符数组,获取到每一个字符
		for(char ch:chs) {
			//获取到每一个字符
			Integer i = hm.get(ch) ; //肯定要把值获取到
			System.out.println(i);
			
			//通过put方法添加元素,看这个值是否为null
			if(i==null) {
				//第一次存储
				hm.put(ch, 1);
			}else {
				//不是null,存储了多次
				i ++ ;
				hm.put(ch, i) ;
			}
		}
		
		//创建一个字符串缓冲区对象
		StringBuilder sb  = new StringBuilder() ;
		//遍历HashMap集合
		Set<Character> set = hm.keySet() ;
		for(Character key :set) {
			//获取值
			Integer value = hm.get(key) ;
			sb.append(key).append("(").append(value).append(")") ;
		}
		
		String str = sb.toString() ;
		System.out.println("str:"+str);
	}
}


集合的嵌套:

1、HashMap集合嵌套HashMap集合:

jc(基础班)
高圆圆 27
张三 28
 
jy(就业班)
赵又廷 29
李四 30

HashMap<String,HashMap<String,Integer>>

代码如下:

public class QianTao {

	public static void main(String[] args) {
		
	
		//创建一个大集合
		HashMap<String,HashMap<String,Integer>> map = 
					new HashMap<String,HashMap<String,Integer>>();
		
		//创建第一子HashMap集合,存储元素
		HashMap<String, Integer> hm1 = new HashMap<String,Integer>() ;
		hm1.put("高圆圆", 27) ;
		hm1.put("张三", 28) ;
		
		//将第一个子集合添加到大集合中
		map.put("jc", hm1) ;
		
		
		//创建第二个子HashMap集合,存储元素
		HashMap<String, Integer> hm2 = new HashMap<String,Integer>() ;
		hm2.put("赵又廷", 29) ;
		hm2.put("李四",30) ;
		
		//添加到大集合中
		map.put("jy", hm2) ;
		
		//遍历
		Set<String> mapSet = map.keySet() ;
		for(String bigKey :mapSet) {
			System.out.println(bigKey);
			//通过大集合的对象,通过键获取值(HashMap集合)
			
			HashMap<String, Integer> bigValue = map.get(bigKey) ;
			//获取所有的键的集合
			Set<String> smallMap = bigValue.keySet() ;
			for(String smallKey :smallMap) {
				Integer smallValue = bigValue.get(smallKey) ;
				System.out.println("\t"+smallKey+"---"+smallValue);
			}
		}
	}
}

2、HashMap集合嵌套ArrayList集合

需求:

  三国演义
  吕布
  周瑜
  笑傲江湖
  令狐冲
  林平之
  神雕侠侣
  郭靖
  杨过 

HashMap<String,ArrayList<String>>

public class HashMapIncludeArrayListTest {
	
	public static void main(String[] args) {
		
		//创建一个大集合对象
		HashMap<String, ArrayList<String>> hm = new HashMap<String,ArrayList<String>>() ;
		
		//创建第一个子集合对象
		ArrayList<String> array1 = new ArrayList<String>() ;
		array1.add("吕布") ;
		array1.add("周瑜") ;
		
		//添加到集合中
		hm.put("三国演义", array1) ;
		
		//创建第二个子集合对象
		ArrayList<String> array2 = new ArrayList<String>() ;
		array2.add("令狐冲") ;
		array2.add("林平之") ;
		
		//添加到集合中
		hm.put("笑傲江湖", array2) ;
		
		
		//创建第二个子集合对象
		ArrayList<String> array3 = new ArrayList<String>() ;
		array3.add("郭靖") ;
		array3.add("杨过") ;
		
		//添加到集合中
		hm.put("神雕侠侣", array3) ;
		
		//遍历
		Set<String> set = hm.keySet() ;
		for(String key :set) {
			System.out.println(key) ;
			
			//通过key获取value
			ArrayList<String> value = hm.get(key) ;
			for(String s: value) {
				System.out.println("\t"+s);
			}
		}
 	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值