Java SE 集合:Map接口
Java SE 集合:Map接口
目录
Values ,HashTable ,CollectionsHashMap 同步
1、Set 接口 hashSet
-
无序,去重
-
HashSet的底层是用 HashMap 实现的
-
底层结构: 哈希表(数组+链表+红黑树) 不同步
-
特点:
做查询,增删效率较高
无序去重 -
初始容量: 16
加载因子: 0.75 ->扩容的临界点 -
扩容的临界点 = 容量*加载因子;
12 = 16*0.75; 当存储的数据到12就扩容
注意:
HashSet 与 TreeSet之间的选择
如果想要数据存储的时候默认升序|降序->TreeSet
否则建议选择HashSet
1.1 构造器
构造器 | 描述 |
---|---|
HashSet() | 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。 |
HashSet(int initialCapacity) | 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。 |
HashSet(int initialCapacity, float loadFactor) | 构造一个新的空集; 支持HashMap实例具有指定的初始容量和指定的加载因子。 |
HashSet(Collection<? extends E> c) | 构造一个包含指定集合中元素的新集合。 |
//HashSet() 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
HashSet<String> hs=new HashSet<>();
//HashSet(int initialCapacity) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。
HashSet<String> hs2=new HashSet<>(20);
1.2 常用方法(一些)
变量和类型 | 方法 | 描述 |
---|---|---|
boolean | add(E e) | 如果指定的元素尚不存在,则将其添加到此集合中。 |
void | clear() | 从该集中删除所有元素。 |
Object | clone() | 返回此 HashSet实例的浅表副本:未克隆元素本身。 |
boolean | contains(Object o) | 如果此set包含指定的元素,则返回 true 。 |
boolean | isEmpty() | 如果此集合不包含任何元素,则返回 true 。 |
Iterator | iterator() | 返回此set中元素的迭代器。 |
boolean | remove(Object o) | 如果存在,则从该集合中移除指定的元素。 |
int | size() | 返回此集合中的元素数(基数)。 |
1.2.1 如何构建存储引用数据类型集合
构建一个HashSet 存储自定义引用数据类型的数据,做基本操作行为,然后遍历 |
---|
通过HashSet存储自定义引用数据类型的数据去重问题: 需要在自定义引用数据类型中,重写hashcode与equals方法,根据内容计算比较 |
hashcode 与 equals : equals相等hashcode值肯定相等 hashcode相等,equals不一定相等 |
HashSet<Person> hash = new HashSet<>();
//默认根据地址做去重
hash.add(new Person("",18));
hash.add(new Person("",18));
System.out.println(hash);
System.out.println(new Person("",18).hashCode());
System.out.println(new Person("",18).hashCode());
//HashSet() 构造一个新的空集; 支持HashMap实例具有默认初始容量(16)和加载因子(0.75)。
//HashSet(int initialCapacity) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和默认加载因子(0.75)。
//HashSet(int initialCapacity, float loadFactor) 构造一个新的空集; 支持HashMap实例具有指定的初始容量和指定的加载因子。
//HashSet(Collection<? extends E> c) 构造一个包含指定集合中元素的新集合。
HashSet<String> hs=new HashSet<>();
hs.add("aja");
//boolean add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
hs.add("gkdlg");
//void clear() 从该集中删除所有元素。
//Object clone() 返回此 HashSet实例的浅表副本:未克隆元素本身。
//boolean contains(Object o) 如果此set包含指定的元素,则返回 true 。
System.out.println(hs.contains("gkdlg"));
//boolean isEmpty() 如果此集合不包含任何元素,则返回 true 。
System.out.println(hs.isEmpty());
//Iterator<E> iterator() 返回此set中元素的迭代器。
//Iterator iterator= hs.iterator();
//boolean remove(Object o) 如果存在,则从该集合中移除指定的元素。
hs.remove("gkdlg");
//int size() 返回此集合中的元素数(基数)。
System.out.println( hs.size());
//Spliterator<E> spliterator() 在此集合中的元素上创建late-binding和失败快速 Spliterator 。
1.3 遍历
//遍历
for (String s:hs) {
System.out.println(s);
}
//迭代器
Iterator ia= hs.iterator();
while(ia.hasNext()){
System.out.println(ia.next());
}
2、Map 接口
常见的实现类有 HashMap 、 HashTable 等
- Map<K,V>
- 接口
- 存储键值对的数据
- k-v 一个映射关系:key->value;一个key只能对应一个value
- key与value可以为任意类型的一个数据
- key是唯一的,无序的 --> Set集合
- value是无序可重复的 --> Collection 无序可重复
注意:如果存入的键值对中key相同,那么后面的会覆盖掉前面的数据存放到Map之后,我们是无
法控制存放数据的顺序的
2.1、遍历方式:
- Set< K> keySet() 返回所有的key,通过key获取value
- Collection< V> values() 获取集合中的所有value值,无法获取key
- Set<Map.Entry<K,V>> entrySet()
//多态
Map<Integer,String> map=new HashMap<>();
// 遍历
//Set<K> keySet() 返回所有的key,通过key获取value
System.out.println("-------- Set<K> keySet() 返回所有的key,通过key获取value-------------");
Set<Integer> set=map.keySet();
for (int s:set) {
System.out.println(s+"-->"+map.get(s));
}
//Collection<V> values() 获取集合中的所有value值,无法获取key
System.out.println("-------- Collection<V> values() 获取集合中的所有value值,无法获取key-------------");
Collection<String> con=map.values();
for (String s:con) {
System.out.println(s);
}
//Set<Map.Entry<K,V>> entrySet()
System.out.println("--------Set<Map,Entry<K,V>> entrySet()-------------");
Set<Map.Entry<Integer,String>> st=map.entrySet();
for (Map.Entry <Integer,String > m:st) {
System.out.println(m);
}
3、 HashMap
HashMap作为Map的实现类,其中的方法都进行了实现,并且定义了可以存储数据的空间,其中使用了
一个叫做 Entry 的内部类,作为数据的存储
-
HashSet --> HashMap 不同步
-
底层结构:
哈希表(数组+链表+红黑树) -
特点:
- 存储键值对类型数据
- 无序,根据key做去重
- 查询,修改,删除,增加效率较高
-
Hash表存储原理:
哈希表: Node节点数组,存储节点数据 节点:key,value,hash,next
1.**put(key,value)**存储键值对类型的数据
构建一个Node节点对象 new Node(key,value,hash,null) -
默认初始容量: 1<<4 16–> 数组长度
-
加载因子 : 0.75
-
最大容量… 1<<30
-
扩容: 新数组的容量为原容量的2倍 newCap = oldCap << 1
当添加的数据个数>=原数组长度*0.75 的时候,就扩容,扩容的是数组的大小
HashMap存储key如果为自定义引用数据类型:
key去重的问题 : key类型中要求重写hashcode与equals方法
3.1、构造器
构造器 | 描述 |
---|---|
HashMap() | 使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。 |
HashMap(int initialCapacity) | 使用指定的初始容量和默认加载因子(0.75)构造一个空 HashMap 。 |
HashMap(int initialCapacity, float loadFactor) | 使用指定的初始容量和加载因子构造一个空 HashMap 。 |
HashMap(Map<? extends K,? extends V> m) | 构造一个新的 HashMap ,其映射与指定的 Map相同。 |
//HashMap()使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。
Map<Integer,String> map=new HashMap<>();
//HashMap(int initialCapacity, float loadFactor)使用指定的初始容量和加载因子构造一个空 HashMap 。
HashMap<Integer,User> hash = new HashMap<>(20,0.8);
3.2、常用方法(一些)
变量和类型 | 方法 | 描述 |
---|---|---|
void | clear() | 从此映射中删除所有映射。 |
Object | clone() | 返回此 HashMap实例的浅表副本:未克隆键和值本身。 |
V | compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 尝试计算指定键及其当前映射值的映射(如果没有当前映射, null )。 |
V | computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | 如果指定的键尚未与值关联(或映射到 null ),则尝试使用给定的映射函数计算其值并将其输入此映射,除非 null 。 |
V | computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 如果指定键的值存在且为非null,则尝试在给定键及其当前映射值的情况下计算新映射。 |
boolean | containsKey(Object key) | 如果此映射包含指定键的映射,则返回 true 。 |
boolean | containsValue(Object value) | 如果此映射将一个或多个键映射到指定值,则返回 true 。 |
Set<Map.Entry<K,V>> | entrySet() | 返回此映射中包含的映射的Set视图。 |
V | get(Object key) | 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。 |
boolean | isEmpty() | 如果此映射不包含键 - 值映射,则返回 true 。 |
Set | keySet() | 返回此映射中包含的键的Set视图。 |
V | merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | 如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。 |
V | put(K key, V value) | 将指定的值与此映射中的指定键相关联。 |
void | putAll(Map<? extends K,? extends V> m) | 将指定映射中的所有映射复制到此映射。 |
V | remove(Object key) | 从此映射中删除指定键的映射(如果存在)。 |
int | size() | 返回此映射中键 - 值映射的数量。 |
Collection | values() | 返回此映射中包含的值的Collection视图。 |
HashMap存储key如果为自定义引用数据类型:
key去重的问题 : key类型中要求重写hashcode与equals方法
Map<Integer,String> map=new HashMap<>();
//V put(K key, V value) 将指定的值与此映射中的指定键相关联(可选操作)。
map.put(1001,"haha");
map.put(1010,"zss");
map.put(1005,"hjfnks");
map.put(1002,"vghdjkgv");
map.put(1004,"sfskl");
map.put(1012,"dsjkv");
System.out.println(map);
// 遍历
//Set<K> keySet() 返回所有的key,通过key获取value
System.out.println("-------- Set<K> keySet() 返回所有的key,通过key获取value-------------");
Set<Integer> set=map.keySet();
for (int s:set) {
System.out.println(s+"-->"+map.get(s));
}
//Collection<V> values() 获取集合中的所有value值,无法获取key
System.out.println("-------- Collection<V> values() 获取集合中的所有value值,无法获取key-------------");
Collection<String> con=map.values();
for (String s:con) {
System.out.println(s);
}
//Set<Map.Entry<K,V>> entrySet()
System.out.println("--------Set<Map,Entry<K,V>> entrySet()-------------");
Set<Map.Entry<Integer,String>> st=map.entrySet();
for (Map.Entry <Integer,String > m:st) {
System.out.println(m);
}
System.out.println("==================================");
//V get(Object key) 根据key获取value,没有返回null
System.out.println(map.get(1005));
//int size()
System.out.println(map.size());
//boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
//boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
System.out.println(map.containsKey(1012)); //true
System.out.println(map.containsValue("zss"));//true
//V remove(Object key) 如果存在,则从该映射中移除键的映射(可选操作)。
System.out.println(map.remove(1021));// nulls
//default V replace(K key, V value) 仅当指定键当前映射到某个值时,才替换该条目的条目。
System.out.println(map.remove(1021,"hahd"));//flase
//default boolean replace(K key, V oldValue, V newValue) 仅当前映射到指定值时,才替换指定键的条目。
System.out.println(map.replace(1001,"haha","heihei"));//true
4、TreeMap
- extends AbstractMap<K,V>
- TreeSet底层就是由TreeMap维护的
- 底层结构: 红黑树
- 特点: 有序(默认升序排序),存放存储与内部真实存储顺序是不一致的
- 此实现不同步
- 注意: 以后什么功能|结构能够实现排序的,想到比较器:指定比较规则
去重排序: 根据key实现去重与排序
key中存放的数据的类型->1)实现内部比较器 2)实现外部比较器
TreeMap<Student,String> trst=new TreeMap<>();
存储数据,在存储的时候才会比较,排序
trst.put(new Student(1020,"haha",20,'男'),"大数据");
trst.put(new Student(1002,"dudu",22,'男'),"java");
trst.put(new Student(1001,"cici",21,'男'),"大数据");
trst.put(new Student(1014,"bibi",24,'男'),"html");
map.put(null,null); //treemap中存储键值对key不能为null
System.out.println(trst);
//外部比较器
TreeMap<Student,String> trst2=new TreeMap<>((o1, o2) -> o1.getName().compareTo(o2.getName()));
trst2.putAll(trst);
System.out.println(trst2);
5、HashTable
- 实现了一个哈希表,它将键映射到值。 任何非
null
对象都可以用作键或值。 -
初始容量和负载因子 。 容量是哈希表中的桶数, 初始容量只是创建哈希表时的容量。
- 默认初始容量(11)和加载因子(0.75)
- extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
构造器 | 描述 |
---|---|
Hashtable() | 使用默认初始容量(11)和加载因子(0.75)构造一个新的空哈希表。 |
Hashtable(int initialCapacity, float loadFactor) | 使用指定的初始容量和指定的加载因子构造一个新的空哈希表。 |
变量和类型 | 方法 | 描述 |
---|---|---|
void | clear() | 清除此哈希表,使其不包含任何键。 |
V | compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 尝试计算指定键及其当前映射值的映射(如果没有当前映射, null )。 |
boolean | contains(Object value) | 测试某些键是否映射到此哈希表中的指定值。 |
boolean | containsKey(Object key) | 测试指定的对象是否是此哈希表中的键。 |
boolean | containsValue(Object value) | 如果此哈希表将一个或多个键映射到此值,则返回true。 |
Enumeration | elements() | 返回此哈希表中值的枚举。 |
Set<Map.Entry<K,V>> | entrySet() | 返回此映射中包含的映射的Set视图。 |
boolean | equals(Object o) | 根据Map接口中的定义,将指定的Object与此Map进行相等性比较。 |
V | get(Object key) | 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。 |
int | hashCode() | 根据Map接口中的定义返回此Map的哈希码值。 |
boolean | isEmpty() | 测试此哈希表是否将键映射到值。 |
Enumeration | keys() | 返回此哈希表中键的枚举。 |
Set | keySet() | 返回此映射中包含的键的Set视图。 |
V | merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | 如果指定的键尚未与值关联或与null关联,则将其与给定的非空值关联。 |
V | put(K key, V value) | 将指定的 key映射到此哈希表中的指定 value 。 |
void | putAll(Map<? extends K,? extends V> t) | 将指定映射中的所有映射复制到此哈希表。 |
protected void | rehash() | 增加此哈希表的容量并在内部重新组织,以便更有效地容纳和访问其条目。 |
V | remove(Object key) | 从此哈希表中删除键(及其对应的值)。 |
int | size() | 返回此哈希表中的键数。 |
String | toString() | 以一组条目的形式返回此 Hashtable对象的字符串表示形式,用大括号括起,并用ASCII字符“ , ”(逗号和空格)分隔。 |
Collection | values() | 返回此映射中包含的值的Collection视图。 |
5.2、Properties
Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
- 存储的键值对都为字符串类型
- Properties类表示一组持久的属性。
- extends Hashtable<Object,Object>
- Properties可以保存到流中或从流中加载。
总结:
-
properties作为配置文件使用的步骤:
- 1.src下新建一个file文件,名字问xx.properties
- 2.zai配置文件中定义键值对为字符串的数据(注意不加"",;…)
- 3.程序中定义个Properties对象.通过对象.load(流) 指定从某一个资源文件中读取数据,使用指定的流
- 4.对象.getProperty(key)
-
properties根式作为配置文件的格式存在,键值对 都是字符串,简单
-
程序从properties文件中读取数据:
void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。
5.2.1、构造器
构造器 | 描述 |
---|---|
Properties() | 创建一个没有默认值的空属性列表。 |
Properties(int initialCapacity) | 创建一个没有默认值的空属性列表,并且初始大小容纳指定数量的元素,而无需动态调整大小。 |
Properties(Properties defaults) | 创建具有指定默认值的空属性列表。 |
5.2.2、常用方法
变量和类型 | 方法 | 描述 |
---|---|---|
String | getProperty(String key) | 在此属性列表中搜索具有指定键的属性。 |
String | getProperty(String key, String defaultValue) | 在此属性列表中搜索具有指定键的属性。 |
void | list(PrintWriter out) | 将此属性列表打印到指定的输出流。 |
void | load(InputStream inStream) | 从输入字节流中读取属性列表(键和元素对)。 |
Properties ppt=new Properties();
//新增方法
ppt.setProperty("123","456");
//通过properties对象从配置文件中读取数据
//指定从哪一个文件,通过哪个流加载
ppt.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("week04/day01/properties02/hhh.properties"));
System.out.println(ppt.getProperty("name1"));
System.out.println(ppt.getProperty("sex1"));
System.out.println(ppt.getProperty("name2"));
System.out.println(ppt.getProperty("sex2"));
System.out.println(ppt.getProperty("嘿嘿"));
6、Collections
Collections 与 Collection 之间的区别:
- Collection 集合体系的上层接口
- Collections 操作集合数据的工具类 , 与 Arrays很像
常用方法:
-
void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
-
void shuffle(List) //对List容器内的元素进行随机排列
-
void reverse(List) //对List容器内的元素进行逆续排列
-
void fill(List, Object) //用一个特定的对象重写整个List容器
-
int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
使用前提: 升序排序
HashMap线程不安全问题:
- 1.Hashtable类型,线程安全类型的Map
- Hashtable是同步的。 如果不需要线程安全实现,建议使用HashMap代替Hashtable 。 如果需要线程安全的高度并发实现,则建议使用ConcurrentHashMap代替Hashtable 。
- 2.Collections -> static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) 返回由指定映射支持的同步(线程安全)映射。
- 3.juc包(高级并发编程包) - > ConcurrentHashMap 线程安全的哈希表—>推荐,安全性好效率高
List<Integer> lt=new ArrayList<>();
lt.add(23);
lt.add(34);
lt.add(56);
lt.add(86);
lt.add(1);
System.out.println(lt);
//void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
Collections.sort(lt);
System.out.println(lt);
// void shuffle(List) //对List容器内的元素进行随机排列
Collections.shuffle(lt);
System.out.println(lt);
// void reverse(List) //对List容器内的元素进行逆续排列
Collections.reverse(lt);
System.out.println(lt);
// void fill(List, Object) //用一个特定的对象重写整个List容器
Collections.fill(lt,56);
System.out.println(lt);
// int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
// 使用前提: 升序排序
Collections.sort(lt);
Collections.binarySearch(lt,34);
System.out.println(lt);
Values ,HashTable ,CollectionsHashMap 同步
上一篇: Java之动态代理