Map接口

键值对<key,value>

Interface Map<K,V>

  • 参数类型

    K - 由此地图维护的键的类型

    V - 映射值的类型

public class TestMap {public static void main(String[] args) {/** 增加:put(K key, V value)* 删除:clear();remove(Object key);* 修改:* 查看:entrySet();get(Object key);keySet();values();size()* 判断:containsKey(Object key);containsValue(Object value);equals(Object o);isEmpty()* *///创建一个Map集合:唯一,无序Map<String,Integer> map=new HashMap<>();System.out.println(map.put("sky", 502));//null;put的返回值是v,即这里的integermap.put("lsj",426);map.put("yhm",456);map.put("zrp",1715110092);System.out.println(map.put("sky", 374));//502System.out.println(map.size());//4System.out.println(map);//{sky=374, lsj=426, zrp=1715110092, yhm=456}/*map.clear();清空System.out.println(map.size());//0System.out.println(map);//{}*//*map.remove("sky");移除System.out.println(map.size());//3System.out.println(map);//{lsj=426, zrp=1715110092, yhm=456}*/System.out.println(map.containsKey("swy"));//falseSystem.out.println(map.containsValue(426));//trueMap<String,Integer> map2=new HashMap<>();map2.put("sky", 502);//null;put的返回值是v,即这里的integermap2.put("lsj",426);map2.put("yhm",456);map2.put("zrp",1715110092);map2.put("sky", 374);System.out.println(map==map2);//falseSystem.out.println(map.equals(map2));//equals进行了重写比较的是集合中值,内容是否一样;trueSystem.out.println(map.isEmpty());//判断是否为空;falseSystem.out.println(map.get("sky"));//374//遍历:Set<String> set = map.keySet();//keySet()对集合中的key进行遍历查看System.out.println("===============");for(String s:set){System.out.println(s);}System.out.println(map.keySet());//[sky, lsj, zrp, yhm]//获取value的两种方式Collection<Integer> values = map.values();//values()对集合中的value进行查看System.out.println("===============");for(Integer i:values){System.out.println(i);}System.out.println(map.values());//[374, 426, 1715110092, 456]//不用values()方法对value进行遍历Set<String> set2 = map.keySet();for(String s:set2){System.out.println(map.get(s));}System.out.println("===============");Set<Map.Entry<String, Integer>> entries = map.entrySet();//返回set集合//Entry是Map接口里的一个内部接口for(Map.Entry<String, Integer> e:entries){System.out.println(e.getKey()+"-----"+e.getValue());}}
}

上面HashMap换成Hashtable,输出结果不变

HashMap实现类

特点:唯一,无序;不允许k的值重复

HashMap与Hashtable区别:

Map<String,Integer> map3=new Hashtable<>();
//map3.put(null,1010);//Exception in thread "main" java.lang.NullPointerException
//对于hashtable来说,key不可以是null值,存了会报错
Map<String,Integer> map4=new HashMap<>();
System.out.println(map4.put(null, 1010));//null
System.out.println(map4.put(null, 2020));//可以存放多个空
System.out.println(map4);//{null=2020}

LinkedHashMap实现类

特点:有序,唯一

LinkedHashMap<String,Integer> lmap=new LinkedHashMap<>();
lmap.put("asky",502);
lmap.put("bsky",502);
lmap.put("csky",502);
lmap.put("sky",502);
System.out.println(lmap);//{asky=502, bsky=502, csky=502, sky=502}

TreeMap实现类

1、key的类型为String类型

public class TestTreeMap {public static void main(String[] args) {Map<String,Integer> map=new TreeMap<>();map.put("bsky", 502);map.put("alsj",426);map.put("byhm",456);map.put("czrp",1715110092);map.put("dsky", 374);System.out.println(map.size());//5System.out.println(map);//{alsj=426, bsky=502, byhm=456, czrp=1715110092, dsky=374}//String底层已经实现了比较器}
}

2、key的类型是一个自定义的类型

(1)内部比较器

(2)外部比较器

Map<Student,Integer> m1=new TreeMap<>();
m1.put(new Student(19,168.3,"flili"),103);
m1.put(new Student(18,168.3,"blili"),123);
m1.put(new Student(11,168.3,"clili"),1023);
m1.put(new Student(17,168.3,"dlili"),111);
m1.put(new Student(16,168.3,"alili"),167);
m1.put(new Student(20,168.3,"glili"),88);
System.out.println(m1);//按自己定义的比较器进行排序
System.out.println(m1.size());//6Map<Student,Integer> m1=new TreeMap<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge()-o2.getAge();}});//匿名内部类的外部比较器

HashMap的简单原理

JDK1.7版本

提出问题:

public class OriHashMap {public static void main(String[] args) {//创建hashmap对象:存储的是双列数据,键值对key-valueHashMap<Integer,String> hm=new HashMap<>();System.out.println(hm.put(12, "sky"));//nullSystem.out.println(hm.put(7, "feifei"));//nullSystem.out.println(hm.put(19, "lulu"));//nullSystem.out.println(hm.put(12, "mingming"));//sky//这个12是sky的12还是mingming的12?System.out.println(hm.put(2, "yhm"));//nullSystem.out.println(hm.size());//4System.out.println(hm);//{2=yhm, 19=lulu, 7=feifei, 12=mingming}}
}

答:12是sky的12

七上八下:jdk7链表头插法;jdk8尾插法

jdk1.7版源码
//1.hashmap的k,v值,在创建对象时确定
//hashmap的父类AbstractMap已经实现了Map接口,但源码中又单独实现了Map,这是多余的,错的,arraylist同理
public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable //重要属性static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16,一会儿赋值给数组的长度static final int MAXIMUM_CAPACITY = 1 << 30;//定义了一个很大很大的数static final float DEFAULT_LOAD_FACTOR = 0.75f;//定义了一个值:0.75 装填因子,负载因子,加载因子transient Entry<K,V>[] table;//底层主数组transient int size;//集合中添加元素的数量int threshold;//定义了变量,没赋值默认为0-----》数组扩容的边界值final float loadFactor;//用来接收装填因子,负载因子,加载因子


put原理

put方法源码:



数组扩容原理

数组扩容的边界值是指?size超过12就扩容?

不是,是要size超过12且目标位置不为空才会扩容

经典面试题

1、装填因子,负载因子,加载因子为什么是0.75?

装填因子设置为1:空间利用率得到了很大的满足,很容易碰撞,产生链表------》查询效率低

装填因子设置为0.5:碰撞的概率第,扩容,产生链表的几率低------》查询效率高;空间利用率太低了

所以在0.5-1中取了一个中间值0.75

2、主数组的长度为什么必须为2^n?

HashSet底层原理

public class HashSet<E>{//重要属性:private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();//构造器public HashSet() {map = new HashMap<>();}public boolean add(E e) {return map.put(e, PRESENT)==null;}
}

TreeMap底层源码

二叉树就是红黑树

public class TreeMap<K,V>{//重要属性://外部比较器private final Comparator<? super K> comparator;//树的根节点private transient Entry<K,V> root;//集合中元素的数量private transient int size = 0;//空构造器public TreeMap() {comparator = null;//如果使用空构造器,那么底层就不使用外部比较器}//有参构造器public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;//如果使用了有参构造器,那么相当于指定了外部比较器}static final class Entry<K,V> implements Map.Entry<K,V> {K key;V value;Entry<K,V> left;Entry<K,V> right;Entry<K,V> parent;boolean color = BLACK;}public V put(K key, V value) {//K,V的类型在创建对象时确定//如果放入的时第一对元素,那么t的值为nullEntry<K,V> t = root;//放入第二个元素时,root不为空,不走if//如果放入的时第一个元素的话,走入这个if中if (t == null) {//自己与自己比较compare(key, key); // type (and possibly null) check//根节点确定为rootroot = new Entry<>(key, value, null);//size变成1size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable paths//将外部比较器赋值给cpr:Comparator<? super K> cpr = comparator;//cpr不等于null意味着创建对象时调用了有参构造器,指定了外部比较器if (cpr != null) {do {parent = t;cmp = cpr.compare(key, t.key);//将元素的key值做比较//cmp返回int类型数据if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else//cmp==0;//如果key的值一样,那么新的value替换老的value,但是key不变,key唯一return t.setValue(value);} while (t != null);}//cpr等于null意味着创建对象时调用了空构造器,没有指定外部比较器,使用内部比较器else {if (key == null)throw new NullPointerException();@SuppressWarnings("unchecked")Comparable<? super K> k = (Comparable<? super K>) key;do {parent = t;cmp = k.compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;fixAfterInsertion(e);size++;//size加一操作modCount++;return null;}
}

TreeSet源码

public class TreeSet<E> extends AbstractSet<E>implements NavigableSet<E>, Cloneable, java.io.Serializable{//重要属性:private transient NavigableMap<E,Object> m;private static final Object PRESENT = new Object();//调用空构造器时底层创建了一个TreeMappublic TreeSet() {this(new TreeMap<E,Object>());}TreeSet(NavigableMap<E,Object> m) {this.m = m;}//实际上时treemap的put方法public boolean add(E e) {return m.put(e, PRESENT)==null;}
}

Collections工具类

public class TestCols {public static void main(String[] args) {//collections不支持创建对象,因为构造器私有化//属性和方法通过类名调用//常用方法:addAllArrayList<String> list=new ArrayList<>();list.add("cc");list.add("aa");list.add("bb");Collections.addAll(list,"dd","ff");Collections.addAll(list,new String[]{"sky","lsj","yhm"});System.out.println(list);//sort升序排列Collections.sort(list);System.out.println(list);//binarySearch:前提,集合内容有序int i=Collections.binarySearch(list,"cc");System.out.println(i);//copy:把list2里面的内容替换到list里面ArrayList<String> list2=new ArrayList<>();Collections.addAll(list2,"tt","ss");Collections.copy(list,list2);System.out.println("============");System.out.println(list);System.out.println(list2);//fill:填充,把list2里面的所有内容填充为yyCollections.fill(list2,"yy");System.out.println(list2);}
}

chapter11集合(2)相关推荐

  1. chapter11集合(1)

    前言 有人也称之为容器 高斯算法 跳转结构(链式结构):单向链表:双向链表:循环链表(双向基础): 优点:删除和插入元素效率高 缺点:查询元素效率低 集合 数组和集合都是用来对多个数据进行存储操作的, ...

  2. do还是doing imagine加to_中学必背英语短语集合:54个doing动名词的固定搭配

    中学必背英语短语集合:54个doing动名词的固定搭配​mp.weixin.qq.com doing动名词是中小学英语教学中的重要内容.在小学的时候老师大概会把doing解释为一般进行时,但层级越往上 ...

  3. Redis 笔记(07)— sorted set 类型(添加、删除有序集合元素、获取分数范围内成员、按score排序、返回集合元素个数)

    zset 可能是 Redis 提供的最为特色的数据结构,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权 ...

  4. Redis 笔记(06)— set 类型(向集合添加元素、获取集合元素个数、判断集合中是否包含某个元素、删除给定元素、返回集合中所有元素、计算集合的交集、并集、差集)

    Redis 的 set 集合内部的键值对是无序的唯一的.它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL .当集合中最后一个元素移除之后,数据结构自动删除,内存被回收. ...

  5. 【C#】集合_哈希表_字典_泛型_文件

    数组能做到:存放同种类型数据,且数据个数确定 object类型的数组能满足:放各种类型的数据,确定放多少个,但是随意插入元素,数组做不到 集合能做到:存放各种数据类型,且不确定存放多少个,能做到随意插 ...

  6. java集合中对象某属性比较排序

    TreeSet:它可以给Set集合中的元素进行指定方式的排序. 保证元素唯一性的方式:通过比较的结果是否为0. 底层数据结构是:二叉树. 排序的第一种方式: 让元素自身具备比较性.只要让元素实现Com ...

  7. 程序员应该吃透的集合List

    一:先看看集合框架接口图 (图片来源于网络) 从图中可以看到List实现了Collection接口. 二:Collection接口是什么? 在java类库中,Collection接口是集合类的基本接口 ...

  8. Java集合详解之Map

    一.首先看看集合框架体系图 从图中可以看到,Map接口扩展了Iterator接口,关于Iterator接口详解请移步:Iterator接口详解 二.Map是什么? Map<k,v>使用键值 ...

  9. 第一个python程序:定义,列表,元组,集合,求并集交集,键和值,运算符,缩进

    ''' 来源:天善智能韦玮老师课堂笔记 ''' print("定义") a = 6 # python里无需定义 print("a=",a) a += 1 # + ...

最新文章

  1. linux汇编div除法,汇编:div 除法指令
  2. 工厂方法模式和抽象工厂模式
  3. python列表的实现原理_Python列表对象实现原理
  4. 利用CSS定位背景图片
  5. 安卓中如何实现滑动导航
  6. linux下/proc/cpuinfo文件
  7. 【资源放送】机器学习/深度学习最全公开视频大放送!
  8. SQL Editor and reconnect【mysql(workbench)更新数据时候的一个异常】【Error Code:1175】
  9. Shell中的if语句中的
  10. 吴恩达【深度学习工程师】 04.卷积神经网络 第四周特殊应用(2)神经风格转换...
  11. PPT将立方体形状变为很薄的长方体
  12. 字节教育大裁员:有员工赔了一套首付款!
  13. wrapper x64 版本发布到centos
  14. 【机器学习系列】隐马尔科夫模型第二讲:前向算法、后向算法
  15. HCIP 3-4月考试战报
  16. java中前加加++和后加加++的详解
  17. 【转载】UMTS和GSM的架构
  18. 传统蓝牙HCI流控(HCI flow control)
  19. ABB机器人模块加密软件,代模块加密,加密之后别人就看不见你 写的程序,也无法打开,但是可以正常运行
  20. mysql按工作日查询统计优化_工作日计算问题思路和实现

热门文章

  1. ssl证书保障网站信息安全是否可靠?
  2. (六)通过pygame让游戏背景图像实现交替滚动
  3. 今夕摄影影楼管理系统
  4. Redis Cluste部署
  5. Lesson 25 Do the English speak English? 英国人讲的是英语吗?
  6. 软件测试有哪些前景?
  7. 用javascript生成屏幕尺
  8. HTML常用的一些标签(推荐)
  9. 高光谱数据集 Houston 2013, 2018
  10. 360安全,3Q大战一夜爆红