chapter11集合(2)
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)相关推荐
- chapter11集合(1)
前言 有人也称之为容器 高斯算法 跳转结构(链式结构):单向链表:双向链表:循环链表(双向基础): 优点:删除和插入元素效率高 缺点:查询元素效率低 集合 数组和集合都是用来对多个数据进行存储操作的, ...
- do还是doing imagine加to_中学必背英语短语集合:54个doing动名词的固定搭配
中学必背英语短语集合:54个doing动名词的固定搭配mp.weixin.qq.com doing动名词是中小学英语教学中的重要内容.在小学的时候老师大概会把doing解释为一般进行时,但层级越往上 ...
- Redis 笔记(07)— sorted set 类型(添加、删除有序集合元素、获取分数范围内成员、按score排序、返回集合元素个数)
zset 可能是 Redis 提供的最为特色的数据结构,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权 ...
- Redis 笔记(06)— set 类型(向集合添加元素、获取集合元素个数、判断集合中是否包含某个元素、删除给定元素、返回集合中所有元素、计算集合的交集、并集、差集)
Redis 的 set 集合内部的键值对是无序的唯一的.它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL .当集合中最后一个元素移除之后,数据结构自动删除,内存被回收. ...
- 【C#】集合_哈希表_字典_泛型_文件
数组能做到:存放同种类型数据,且数据个数确定 object类型的数组能满足:放各种类型的数据,确定放多少个,但是随意插入元素,数组做不到 集合能做到:存放各种数据类型,且不确定存放多少个,能做到随意插 ...
- java集合中对象某属性比较排序
TreeSet:它可以给Set集合中的元素进行指定方式的排序. 保证元素唯一性的方式:通过比较的结果是否为0. 底层数据结构是:二叉树. 排序的第一种方式: 让元素自身具备比较性.只要让元素实现Com ...
- 程序员应该吃透的集合List
一:先看看集合框架接口图 (图片来源于网络) 从图中可以看到List实现了Collection接口. 二:Collection接口是什么? 在java类库中,Collection接口是集合类的基本接口 ...
- Java集合详解之Map
一.首先看看集合框架体系图 从图中可以看到,Map接口扩展了Iterator接口,关于Iterator接口详解请移步:Iterator接口详解 二.Map是什么? Map<k,v>使用键值 ...
- 第一个python程序:定义,列表,元组,集合,求并集交集,键和值,运算符,缩进
''' 来源:天善智能韦玮老师课堂笔记 ''' print("定义") a = 6 # python里无需定义 print("a=",a) a += 1 # + ...
最新文章
- linux汇编div除法,汇编:div 除法指令
- 工厂方法模式和抽象工厂模式
- python列表的实现原理_Python列表对象实现原理
- 利用CSS定位背景图片
- 安卓中如何实现滑动导航
- linux下/proc/cpuinfo文件
- 【资源放送】机器学习/深度学习最全公开视频大放送!
- SQL Editor and reconnect【mysql(workbench)更新数据时候的一个异常】【Error Code:1175】
- Shell中的if语句中的
- 吴恩达【深度学习工程师】 04.卷积神经网络 第四周特殊应用(2)神经风格转换...
- PPT将立方体形状变为很薄的长方体
- 字节教育大裁员:有员工赔了一套首付款!
- wrapper x64 版本发布到centos
- 【机器学习系列】隐马尔科夫模型第二讲:前向算法、后向算法
- HCIP 3-4月考试战报
- java中前加加++和后加加++的详解
- 【转载】UMTS和GSM的架构
- 传统蓝牙HCI流控(HCI flow control)
- ABB机器人模块加密软件,代模块加密,加密之后别人就看不见你 写的程序,也无法打开,但是可以正常运行
- mysql按工作日查询统计优化_工作日计算问题思路和实现