一.Map特点
1.无序,键值对,键不能重复,值可以重复
2.键重复则覆盖,没有继承Collection接口
二.遍历方式
1.拿到key,再拿值
2.拿到映射关系,键值都有 取出保存所有Entry的Set,再遍历此Set即可
三.HashMap与Hashtable的区别
1.Hashtable更安全
2.JDK 1.8之前hashtable的key不能存放null
1.2 HashMap(数组+链表+红黑树)
HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快
的访问速度,但遍历顺序却是不确定的。 HashMap 最多只允许一条记录的键为 null,允许多条记
录的值为 null。HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导
致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使
HashMap 具有线程安全的能力,或者使用 ConcurrentHashMap。我们用下面这张图来介绍
HashMap 的结构。
1.3 HashMap的基本原理
put执行过程
public class Demo1 { public static void main(String[] args) { Hashtable<String, Integer> table = new Hashtable<>(); //有 synchronized 锁 安全 table.put("a", 1); table.put("b", 2); Map<String, Integer> map = new HashMap<>(); //增加 map.put("a", 1); map.put("b", 2); map.put("c", 3); map.put("d", 4); System.out.println(map); //删除 Object remove = map.remove("c"); System.out.println(remove); System.out.println(map); //修改 调用put方法 map.put("b", 88); System.out.println(map); //查询单个 System.out.println(map.get("c")); //查询所有 //1.先拿到map集合中的所有key Set keySet = map.keySet(); for (Object key : keySet) { System.out.println("键:"+key+";值:"+map.get(key)); } //2.拿到映射关系 Set<Entry<String, Integer>> entrySet = map.entrySet(); for (Entry<String, Integer> entry : entrySet) { System.out.println("键:"+entry.getKey()+";值:"+entry.getValue()); } }
四.ConcurrentHashMap特点
1.线程安全 由CPU硬件提供并实现的原子操作
2.性能高
3.并发性高 16 个线程并发写
4.分段锁 锁分段技术(JDK8:CAS)
5.键,值不可以为null
五. 泛型
之前:不健壮的代码,会在运行时才会把错误暴露出来
之后:
将潜在的问题暴露出来,早预防早治疗
将运行期出现的异常转换为编译期的错误
public class Demo3 { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); set.add(1); set.add(2); set.add(3); set.add(4); set.add(5); //打印偶数 for (Object obj : set) { if(Integer.valueOf(obj.toString()) % 2 ==0) { System.out.println(obj); } } } } //泛型类 //以前 class BookDao{ //add(Book book) //delete(Book book) } class UserDao extends BaseDao{ } //现在 class BaseDao<T>{ void add(T t) { } void delete(T t) { } } class Result{ //泛型方法 <T> void add(T t) { } }
六.集合之间的相互转换
1.数组转集合:本质上依然是一个数组,长度不可变
2.集合与数组所具备的方法不一样,如对于数组而言,就没有判断内部包含那个元素
public class Demo4 { public static void main(String[] args) { String[] arr= {"a","b","c","d"}; //数组转集合 List<String> list = Arrays.asList(arr); list.add("e"); //集合转数组 Object[] array = list.toArray(); // java.lang.UnsupportedOperationExcept System.out.println(list.size()); } }
七.对于工具类其他方法的应用
1.排序 sort
2.tostring
package com.zking.map; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; /** * 对于工具类其他方法的应用 * 1.排序 sort * 2.tostring * @author PC * */ public class Demo5 { public static void main(String[] args) { /* List<String> list = new ArrayList<>(); list.add("c"); list.add("b"); list.add("y"); System.out.println(list); //排序 Collections.sort(list); System.out.println(list); //改变排序规格 x y 指的是集合中的元素 Collections.sort(list, (x,y) -> y.compareTo(x)); System.out.println(list);*/ List<Person> list = new ArrayList<>(); list.add(new Person("b",12)); list.add(new Person("u",16)); list.add(new Person("c",18)); System.out.println(list); //Collections.sort(list); Collections.sort(list, (x,y) -> x.getName().compareTo(y.getName())); Integer[] arr = {3,5,2,6,7,8}; Arrays.sort(arr); //降序 Arrays.sort(arr, (x,y) -> y-x); //升序 System.out.println(Arrays.toString(arr)); } } class Person /*implements Comparable<Person>*/{ private String name; private int 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; } public Person() { // TODO Auto-generated constructor stub } @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; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public Person(String name, int age) { super(); this.name = name; this.age = age; } /*@Override public int compareTo(Person o) { // TODO Auto-generated method stub return o.getName().compareTo(this.name); }*/ }
八.字符串切割
实现思路
* 1.做字符串切割,得到一个字符组
* 2.再遍历,拿到单个字符
* 3.如果该字符没有出现过,即value值为null,那么该字符为KEY键,值初始化为1
* 4.如果已经出现过,拿到原来的值+1
public class Demo2 { public static void main(String[] args) { String s = "asdfggyehcbckndxbssjjdhggfj"; char[] arr = s.toCharArray(); Map<Character, Integer> map = new TreeMap<>(); for (char c : arr) { Integer value = map.get(c); if(value == null ) { map.put(c, 1); } else { map.put(c, value+1); } } Set<Entry<Character, Integer>> entrySet = map.entrySet(); for (Entry<Character, Integer> entry : entrySet) { System.out.println(entry.getKey()+":"+entry.getValue()); } } }