Java容器---Map基础
1.Map API
(1)Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
java.util Interface Map<K,V> 参数类型:K--Map的Key(键) V--Map的与Key对应的Value(值) 实现的子类:AbstractMap , Attributes , EnumMap , HashMap, Hashtable , LinkedHashMap , |
(2)Map.Entry,是Map的嵌套类,它用来描述Map中的键/值对。
static interface Map.Entry<K,V> :Map条目(键值对)。
(3)覆盖Object 的两个方法,以正确比较 Map 对象的等价性
(4)常用方法
void clear() 从该地图中删除所有的映射(可选操作)。 |
boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true。 |
boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。 |
int size() 返回此地图中键值映射的数量。 |
Collection<V> values() 返回此地图中包含的值的Collection视图。 |
default void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。 |
2.HashMap
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
直接子类:LinkedHashMap , PrinterStateReasons
HashMap基于哈希表(“拉链法”实现哈希表,可参见数据结构-哈希表)实现的Map接口,。 此实现提供了所有可选的Map操作,并允许null的值和null键。
HashMap类大致相当于Hashtable ,除了它是不同步的,如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,那么它必须在外部进行同步。。
这个类不能保证Map的顺序; 特别是,它不能保证订单在一段时间内保持不变。
构造方法 |
HashMap() :构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。(见下面注意) |
HashMap(int initialCapacity) :构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。 |
HashMap(int initialCapacity, float loadFactor) :构造一个空的 HashMap具有指定的初始容量和负载因子。 |
HashMap(Map<? extends K,? extends V> m): 构造一个新的 HashMap与指定的相同的映射 Map 。 |
注意:
HashMap的一个实例有两个影响其性能的参数: 初始容量和负载因子 。 容量是哈希表中的桶数,初始容量只是创建哈希表 (数据结构-哈希表)时的容量。 负载因子是在容量自动增加之前允许哈希表得到满足的度量。 当在散列表中的条目的数量超过了负载因数和容量的乘积,哈希表被重新散列 (即,内部数据结构被重建),使得哈希表具有桶的大约两倍。
作为一般规则,默认负载因子(.75)提供了时间和空间成本之间的良好折中。 更高的值会降低空间开销,但会增加查找成本(反映在 HashMap类的大部分操作中,包括get和put )。 在设置其初始容量时,应考虑Map中预期的条目数及其负载因子,以便最小化重新组播操作的数量。 如果初始容量大于最大条目数除以负载因子,则不会发生重新排列操作。
常用方法和Map相同
3.Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map <K,V>, Cloneable ,Serializable
已知直接子类: Properties , UIDefaults
该类实现了一个哈希表(“拉链法”实现哈希表),它将键映射到值。 任何非null
对象都可以用作键值或值。
为了从散列表成功存储和检索对象,用作键的对象必须实现hashCode
方法和equals
方法。
构造方法 |
Hashtable() :构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。 |
Hashtable(int initialCapacity) :构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。 |
Hashtable(int initialCapacity, float loadFactor): 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。 |
Hashtable(Map<? extends K,? extends V> t) :构造一个与给定地图相同的映射的新哈希表。 |
Hashtable 与HashMap比较
相同点:
- 都实现了Map、Cloneable、Serializable接口
- 底层都是基于“拉链法”实现哈希表
不同的:
- 线程安全不同:HashMap单线程安全,HashTable多线程安全
- NULL的处理不同:HashMap的Key和Value可以为Null,HashTable的Key和Value非 Null
- 遍历:HashMap支持Iterator;HashTable支持Iterator和Enumeration
- 类型不同:HashMap基于AbstractMap,HashTable基于Dictionary
4.TreeMap
public class TreeMap<K,V>
extends AbstractMap <K,V>
implements NavigableMap<K,V>, Cloneable , Serializable
TreeMap基于红黑树实现
NavigableMap。 红黑树是一种自平衡的二叉树,即左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。红黑树虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。(点击查看关于数据结构---红黑树的文章) |
构造方法 |
TreeMap():使用其键的自然排序构造一个新的空树状图。 |
TreeMap(Comparator<? super K> comparator):构造一个新的,空的树图,按照给定的比较器排序。 |
TreeMap(Map<? extends K,? extends V> m) :造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序 。 |
TreeMap(SortedMap<K,? extends V> m) :造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。 |
5.Properties
public class Properties
extends Hashtable <Object ,Object>
直接子类:ProviderProperties类表示一组持久的属性。看参见Java I/O---Properties类(持久化键值对)因为Properties从继承Hashtable时, put种putAll方法可应用于Properties对象。 强烈不鼓励使用它们,因为它们允许调用者插入其键或值不是Strings , 应该使用setProperty方法。这个类是线程安全的:多个线程可以共享一个Properties对象,而不需要外部同步。
构造方法 |
Properties() :创建一个没有默认值的空属性列表。 |
Properties(Properties defaults):创建具有指定默认值的空属性列表。 |
常用方法 |
String getProperty(String key) :使用此属性列表中指定的键搜索属性。 |
String getProperty(String key, String defaultValue) :使用此属性列表中指定的键搜索属性。 |
void list(PrintStream out /PrintWriter out) : 将此属性列表打印到指定的输出流 |
void load(InputStream inStream/Reader reader) : 从输入字节流读取属性列表(键和元素对)。 |
void loadFromXML(InputStream in) :将指定输入流中的XML文档表示的所有属性加载到此属性表中。 |
Enumeration<?> propertyNames() :返回此属性列表中所有键的枚举,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
Object setProperty(String key, String value) :取代 Hashtable方法 put 。 |
void storeToXML(OutputStream os, String comment, String encoding) :使用指定的编码发出表示此表中包含的所有属性的XML文档。 |
Set<String> stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
6.Map的方法演示
public class MapDemo { /** * @param args */ public static void main(String[] args) { Map<Integer,String> map = new HashMap<Integer,String>(); methodDemo(map); /* * 需求:Map集合中存储学号,姓名。 */ } public static void methodDemo(Map<Integer,String> map){ //1,存储键值对。如果键相同,会出现值覆盖。 System.out.println(map.put(3, "xiaoqiang")); System.out.println(map.put(3, "erhu")); map.put(7, "wangcai"); map.put(2, "daniu"); // System.out.println(map.remove(7)); System.out.println(map.get(7)); System.out.println(map); } }
public class MapTest { /** * @param args */ public static void main(String[] args) { /* * 什么时候使用map集合呢? * 当需求中出现映射关系时,应该最先想到map集合。 * */ String cnWeek = getCnWeek(3); System.out.println(cnWeek); String enWeek = getEnWeek("星期八"); System.out.println(enWeek); } //根据中文星期,获取对应的英文星期。 //中文与英文相对应,可以建立表,没有有序的编号,只能通过map集合。 public static String getEnWeek(String cnWeek){ //创建一个表。 Map<String,String> map = new HashMap<String,String>(); map.put("星期一","Monday"); map.put("星期二","Tuesday"); map.put("星期三","Wednesday"); map.put("星期四","Thursday"); map.put("星期五","Friday"); map.put("星期六","Saturday"); map.put("星期日","Sunday"); return map.get(cnWeek); } /** * 根据用户的指定的数据获取对应的星期。 */ public static String getCnWeek(int num){ if(num<=0 || num>7){ throw new NoWeekException(num+",没有对应的星期"); } String[] cnWeeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; return cnWeeks[num]; } }
public class Employee implements Comparable<Employee> { private String name; private int age; public Employee() { super(); } public Employee(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; } @Override public String toString() { return "Emplooye [name=" + name + ", age=" + age + "]"; } @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; Employee other = (Employee) 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 int compareTo(Employee o) { int temp = this.age - o.age; return temp==0? this.name.compareTo(o.name):temp; } } /////////////////////////////////////////////////////////////////////////////////////////// public class HashMapTest { /** * @param args */ public static void main(String[] args) { /* * 1, 将员工和归属存储到HashMap集合中并取出。 同姓名同年龄视为同一个学生。 */ Map<Employee,String> map = new HashMap<Employee,String>();//如果改成LinkedHashMap可以实现有序。 map.put(new Employee("xiaozhang",24),"北京"); map.put(new Employee("laoli",34),"上海"); map.put(new Employee("mingming",26),"南京"); map.put(new Employee("xili",30),"广州"); map.put(new Employee("laoli",34),"铁岭"); Set<Employee> keySet = map.keySet(); for(Employee employee : keySet){ String value = map.get(employee); System.out.println(employee.getName()+":"+employee.getAge()+"...."+value); } // for(Employee employee : map.keySet()){ // // } } }
public class TreeMapTest { /** * @param args */ public static void main(String[] args) { /* * 2, 按照学生的年龄进行升序排序并取出。 按照学生的姓名进行升序排序并取出。 */ // 自定义比较器。 Comparator<Employee> comparator = new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { int temp = o1.getName().compareTo(o2.getName()); return temp == 0 ? o1.getAge() - o2.getAge() : temp; } }; Map<Employee, String> map = new TreeMap<Employee, String>(comparator); map.put(new Employee("xiaozhang", 24), "北京"); map.put(new Employee("laoli", 34), "上海"); map.put(new Employee("mingming", 26), "南京"); map.put(new Employee("xili", 30), "广州"); map.put(new Employee("laoli", 34), "铁岭"); // entrySet Set<Map.Entry<Employee, String>> entrySet = map.entrySet(); for (Map.Entry<Employee, String> me : entrySet) { Employee key = me.getKey(); String value = me.getValue(); System.out.println(key.getName() + "::" + key.getAge() + "....." + value); } } }
2018-01-07
内容主要来自API
Java容器---Map基础的更多相关文章
- Java容器Map接口
Map接口容器存放的是key-value对,由于Map是按key索引的,因此 key 是不可重复的,但 value 允许重复. 下面简单介绍一下Map接口的实现,包括HashMap,LinkedHas ...
- java容器 Map Set List
容器:在java中,如果有一个类专门用来存放其他类的对象,这个类就叫做容器,或者叫集合,集合就是将若干性质相同或者相近的类的对象组合在一起而形成一个整体. boolean add(Object obj ...
- java容器-Map
Map:基本思想是映射表(维护键-值对),HashMap,TreeMap,LinkedHashMap,ConcurrentHashMap等都是基于Map接口实现的map容器,他们特性不同,表现在效率, ...
- Java容器——Map接口
1.定义 Map用于保存存在映射关系<key, value>的数据.其中key值不能重复(使用equals()方法比较),value值可以重复. 2.常用实现类 HashMap:和Hash ...
- 【公开课】【阿里在线技术峰会】魏鹏:基于Java容器的多应用部署技术实践
对于公开课,可能目前用不上这些,但是往往能在以后想解决方案的时候帮助到我.以下是阿里对公开课的整理 摘要: 在首届阿里巴巴在线峰会上,阿里巴巴中间件技术部专家魏鹏为大家带来了题为<基于Java容 ...
- 【Java心得总结七】Java容器下——Map
我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...
- 工作随笔—Java容器基础知识分享(持有对象)
1. 概述 通常,程序总是运行时才知道的根据某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型,为解决这个普遍的编程问题:需要在任意时刻和任意位置创建任意数量的对象,所以,就 ...
- java容器基础
总结一下学过的java容器知识. 一.java容器框架 由于之前学习的java容器类比较混乱,先简单的整理一下java集合框架. 首先,像这种图,网上到处都是,因为这个也算比较准确吧,我也懒得自己画了 ...
- Java 容器(list, set, map)
java容器类库的简化图: (虚线框表示接口, 实线框表示普通的类, 空心箭头表示特定的类实现了接口, 实心箭头表示某个类可以生成箭头所指的类对象) 继承Collection的主要有Set 和 Lis ...
随机推荐
- github与git之间怎么建立连接
git是一款强大的分布式版本控制系统,到底是什么意思呢?其实我也不知道,以后知道了再补上吧.下面咱们来讲一下github怎么与你电脑上的git建立起连接关系. 一.你要有一个github账号. 去百度 ...
- 关于hue安装后出现KeyError: "Couldn't get user id for user hue"的解决方法
首先说明出现此问题的原因是因为你使用的root用户安装了hue,然后在root用户下使用的build/env/bin/supervisor,如下图所示那样: 知道了原因,就容易解决问题了.首先要创建个 ...
- 初识java这个小姑娘(二)
妙解垃圾回收机制 周一,早高峰. 一段考验一个人耐力.智力.开车技术以及脾气的路. 我把车开进了一个没有红绿灯的丁字路口,然后就没有然后了. 来自三个方向的大车小车开始在不大的一块空间里开始互相斗智斗 ...
- Java二分法
public class Dichotomy { //定义查找次数 static int count = 0; public static void main(Str ...
- Linux权限相关操作命令
以下是关于创建用户,设置用户密码,以及查看文件权限,给用户设置权限的一系列操作过程. #查看当前用户的信息[root@VM_64_7_centos tmp]# iduid=0(root) gid=0( ...
- cronlog分割tomcat catalina.out日志
Tomcat 下日志文件 catalina.out 过大,几百兆或几个G,进而造成再也无法写入更多的日志内容,至使 Tomcat 无法处理请求,所以依靠cronlog来分割: 具体步骤如下: 1.安装 ...
- JDK与JRE的关系
JDK = JRE + Java语言 + 工具及工具API JRE = 程序部署发布 + 用户界面工作集 + 集成库 + 其他基础库 + 语言和工具基础库 + Java虚拟机 简单讲:J ...
- 巧用第三方高速开发Android App 热门第三方SDK及框架
巧用第三方高速开发Android App 热门第三方SDK及框架 历经大半年的时间,最终是把这门课程给录制出来了,也就在今天,正式在慕课网上上线了 项目地址:巧用第三方高速开发Android App ...
- iOS开发-自己定义后台显示图片(iOS7-Background Fetch的应用)
之前在用电池医生的时候, 发现它有这样一个功能:当应用进入后台的时候, 会显示另外一张图片覆盖App Switcher显示的界面. 效果例如以下: 变成----> 而这种一个功能, 对于保护用户 ...
- Shuttle ESB(一)——入门实例
下载Shuttle ESB 从GitHub项目公布页,下载最新的公布版本号. Shuttle-ESB源代码包列表:http://www.nuget.org/packages?q=shuttle-esb ...