Java集合"/>
20210323Java集合
Java集合
编辑时间:2021/03/23
读完本节:大概花费40钟,共3530词
文章目录
- Java集合
- 1.集合Collection中存储自定义对象的注意事项
- 2.Java集合之Map接口
- 3.Map实现类之HashMap
- 4.HashMap底层实现原理
- 5.HashMap中重要的常量
- 6.HashMap子类LinkedHashMap
- 7.LinkedHashMap底层实现先后顺序的原理
- 8.HashSet在底层添加元素时的过程
- 9.Map实现类之TreeMap
- 10. Map实现类之Properties
- 11.HashMap、TreeMap、Hashtable三者的区别
- 12.Collections工具类
- ***STAY ANGER!!!***
1.集合Collection中存储自定义对象的注意事项
- 对于List存储自定义对象需要重写equals()方法,删除元素、修改元素、插入元素时需要用到自定义类中的equals()方法确定是否存在元素,然后才是执行操作
- 对于Set分两种情况:
- 对于Set的HashSet、LinkedHashSet实现类,需要重写equals()、hashCode()方法,原因同上。
- 对于Set的TreeSet实现类,需要实现Comparable接口中的compareTo(Object obj)或者Comparator接口中的compare(Object o1, Object o2)
2.Java集合之Map接口
-
Map接口继承树:
-
Map接口:存储双列数据,存储的时key-value对的数据。
-
Map接口有三个实现类:HashMap、TreeMap、Hashtable。
-
HashMap有一个子类LinkedHashMap底层使用链表方式支持;Properties是Hashtable的一个子类,其key和value都是String类型
-
HashMap的底层,在JDK1.7及之前运用了数组+链表;在JDK1.8后运用数组+链表+红黑树
-
Map中的key是无序的、不可重复的,使用Set从存储所有的key,key所在的类需要重写equals()方法和hashCode()方法;Map中的value也是无序的,但可以重复,使用Collection存储所有的value,同样的value所在的类也需要重equals()方法;一个key-value键值对构成了一个Entry对象;Map中的Entry是无序的、不可重复的,使用Set存储所有的Entry
-
Map接口常用的方法:
-
添加、删除、修改操作:
-
Object put(Object key, Object value):将指定的key-value添加到(或修改)到当前map对象中
-
void putAll(Map m):将m中所有的key-value键值对存放到当前Map中
-
Object remove(Object key):移除指定key的key-value键值对,并返回value
-
void clear():清空当前map中的所有数据
import org.junit.Test;import java.util.HashMap; import java.util.Map;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 19:32* @Description:*/ public class MapMethodTest {@Testpublic void test(){//因为Map是一个接口,其中定义的方法都是抽象方法,//因此通过实现类HashMap来展示Map中定义的功能Map map = new HashMap();//添加map.put("AA",123);map.put(456,123);map.put("BB",567);//修改map.put("AA",97);System.out.println(map);Map map1 = new HashMap();map1.put("CC",123);map1.put("DD",123);map.putAll(map1);System.out.println(map);//remove(Object obj)Object value = map.remove("CC");System.out.println(value);System.out.println(map);//clear()map.clear();//与map = null操作不同System.out.println(map.size());System.out.println(map);} }
-
-
元素查询操作:
-
Object get(Object key):获取指定key对应的value
-
boolean containsKey(Object key):是否包含指定的key
-
boolean containsValue(Object value):是否包含指定的Value
-
int size():返回map中key-value键值对的个数
-
boolean isEmpty():判断当前map是否为空
-
boolean equals(Object obj):判断当前map和参数对象obj是否相等
import org.junit.Test;import java.util.HashMap; import java.util.Map;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 19:32* @Description:*/ public class MapMethodTest {@Testpublic void test1(){Map map = new HashMap();map.put("AA",123);map.put(456,123);map.put("BB",567);//找到返回value没找到返回nullSystem.out.println(map.get(456));} }
-
-
元视图的操作方法:
-
Set keySet():返回所有key构成的Set集合
-
Collection values():返回所有value构成的Collection集合
-
Set entrySet():返回所有key-value键值对的构成的Set集合
import org.junit.Test;import java.util.*;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 19:32* @Description:*/ public class MapMethodTest {@Testpublic void test2(){Map map = new HashMap();map.put("AA",123);map.put(456,123);map.put("BB",567);//遍历所有的key集Set set = map.keySet();Iterator iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}System.out.println("*****************");//遍历所有的value集Collection values = map.values();//方式1:采用增强for循环for(Object obj : values){System.out.println(obj);}//遍历所有的key-value//方式一:使用entrySet()Set entrySet = map.entrySet();Iterator iterator1 = entrySet.iterator();while (iterator1.hasNext()){Object obj = iterator1.next();//entrySet集合中的元素都是entryMap.Entry entry = (Map.Entry) obj;System.out.println(entry.getKey() + "----" + entry.getValue());}System.out.println("*****************");//使用keySet和values配合完成遍历所有的key-valueSet keySet = map.keySet();Iterator iterator2 = keySet.iterator();while (iterator2.hasNext()){Object key = iterator2.next();Object value = map.get(key);System.out.println(key + "====" + value);}} }
-
-
Map常用方法小结:
- 添加:put(Object key, Object value)
- 删除:remove(Object key)
- 修改:put(Object key, Object value)
- 查询:get(Object key)
- 长度:size()
- 遍历:keySet() / values() / entrySet()
-
3.Map实现类之HashMap
- HashMap是Map接口中使用频率最高的实现类
- HashMap允许使用null键和null值,与HashSet一样的是,HashMap不能保证映射的顺序
- 所有的key构成的集合是Set,这个Set集合是无序的、不可重复的。所以key所在的类要重写:equals()方法和hashCode()方法
- 所有的value构成的集合是Collection,这个Collection是无序的、可以重复的。所以value所在的类要重写:equals()方法
- 一个键值对构成一个entry,所有的entry构成的集合Set是无序的、不可重复的
- HashMao判断两个key相等的标准是:两个key通过equals返回true,且hashCode值也相等
- HashMap判断两个value相等的标准是:两个value通过equals()方法返回true
- HashMap虽然是线程不安全的,但是提高了效率
4.HashMap底层实现原理
-
在JDK1.7中和JDK1.8中HashMap底层实现原理略有不同
-
HashMap的底层实现原理(JDK1.7环境下):
-
HashMap的实例化过程:
HashMap map = new HashMap()
在实例化完成后,底层创建了一个长度是16的一维数组Entry[] table
-
图示HashMap添加元素的过程:
对于第第二个和第三个判断,其中的key1-value1和原来的数据以链表的方式存储
-
HashMap在元素的添加过程中,底层数组的扩容机制
在向HashMap中不断添加数据的过程中,会涉及扩容问题,当超出临界值(且要存放的位置非空时),扩容为原来容量的两倍(resize(newCapacity * table.length)),并将原有的数据复制到新的Entry[] table数组中。
-
HashMap底层源码(JDK1.7)
-
-
HashMap在JDK1.8中与JDK1.7中底层实现原理的差异
-
new HashMap():实例化HashMap时,底层没有立刻实例化一个长度为16的数组
-
在JDK1.8中,底层数组使用的时Node[] 而非Entry[]
-
在首次调用HashMap的put方法时,底层才创建一个长度为16的Node[]数组
-
JDK1.7底层结构只有:数组+链表;JDK1.8底层结构是:数组+链表+红黑树
- 当满足数组的某一个索引位置上的元素以链表形式存在的数据个数,即链表长度超过8;且当前数组的长度大于64时,此时索引位置上的所有数据改为使用红黑树存储
-
JDK1.8环境下HashMap的底层源码
-
5.HashMap中重要的常量
- DEFAULT_INITIAL_CAPACIRY:HashMap的默认容量16
- MAXIMUM_CAPACIRY:HashMap最大支持容量1^30
- DEFAULT_LOAD_FACTOR:HashMap默认加载因子 0.75
- TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,则将链表转换为红黑树 8
- UNTREEIFY_THRESHOLD:Bucket中红黑树存储的Node小于该默认值,转换为链表
- MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量。64(当桶中Node的数量大到需要转换为红黑树时,若hash表容量小于MIN_TREEIFY_CAPACITY时,此时应执行resize扩容操作,这个MIN_TREEIFY_CAPACITY的值至少是TREEIFY_THRESHOLD的4倍)
- table:存储元素的数组,总是2的n次幂
- entrySet:存储具体元素的集
- size:HashMap中存储的键值对的数量
- modCount:HashMap扩容和改变结构的次数
- threshold:扩容的临界值,等于“容量*填充因子”
- loadFactor:填充因子
6.HashMap子类LinkedHashMap
- LinkedHashMap中定义的内部类与HashMap中定义的内部类不同,HashMap中定义的内部类是Node,LinkedHashMap定义的内部类是Entry,LinkedHashMap定义的Entry内部类,它与HashMap不同的是LinkedHashMap维护了一个贯穿其所有条目的双向链表。这个链表定义了遍历顺序,通常是插入map中的顺序
- LinkedHashMap继承于HashMap,实现了Map接口,重写了父类HashMap中的newNode方法
- 对于频繁的遍历操作,此类执行效率高于HashMap,但是其他的操作(直接向数组中插入元素等)HashMap的效率要更高
7.LinkedHashMap底层实现先后顺序的原理
-
其中的before和after用于记录添加元素的先后顺序
8.HashSet在底层添加元素时的过程
-
HashSet在底层添加元素时,实际上是将元素放入HashMap中的一个key中,且该key指向的是一个Object对象
9.Map实现类之TreeMap
-
保证按照添加的key-value对进行排序,实现遍历排序,此时需要考虑实现Comparable接口中的compareTo(Object obj)方法,或者实现Comparator中的compare(Object o1, Object o2)方法,即考虑key的自然排序或者定制排序;TreeMap底层采用红黑树实现
import org.junit.Test;import java.util.Comparator; import java.util.Iterator; import java.util.Set; import java.util.TreeMap;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 20:02* @Description:*/ public class TreeMapTest {/** 定制排序 */@Testpublic void test2(){TreeMap map = new TreeMap(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof User && o2 instanceof User){User u1 = (User)o1;User u2 = (User)o2;return -Integerpare(u1.getId(),u2.getId());}throw new RuntimeException("输入的类型不匹配!");}});User u1 = new User("Genji", 1);User u2 = new User("Hana", 2);User u3 = new User("Zenyatta", 3);User u4 = new User("Maccree", 4);User u5 = new User("Ashe", 5);map.put(u1,200);map.put(u2,500);map.put(u3,200);map.put(u4,200);map.put(u5,200);Set set = map.keySet();Iterator iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}/** 自然排序 */@Testpublic void test1(){TreeMap map = new TreeMap();User u1 = new User("Genji", 1);User u2 = new User("Hana", 2);User u3 = new User("Zenyatta", 3);User u4 = new User("Maccree", 4);User u5 = new User("Ashe", 5);map.put(u1,200);map.put(u2,500);map.put(u3,200);map.put(u4,200);map.put(u5,200);Set set = map.keySet();Iterator iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}} }
import java.util.Objects;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/22 19:05* @Description:*/ public class User implements Comparable{private String name;private int id;public User() {}public User(String name, int id) {this.name = name;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", id=" + id +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof User)) return false;User user = (User) o;return getId() == user.getId() &&Objects.equals(getName(), user.getName());}@Overridepublic int hashCode() {return Objects.hash(getName(), getId());}/** 输入的性名按照从大到小的顺序排列 */@Overridepublic int compareTo(Object o){if(o instanceof User){User user = (User)o;return -this.namepareTo(user.name);}else{throw new RuntimeException("输入的类型不匹配");}} }
10. Map实现类之Properties
-
Properties是Hashtable的子类,该对象用于处理属性文件
-
由于属性文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型
-
存取数据时,通常使用setProperty(String key, String value)方法和getProperty(String key)方法
import java.io.FileInputStream; import java.io.IOException; import java.util.Properties;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 20:23* @Description:*/ public class PropertiesTest {public static void main(String[] args) {Properties pro = new Properties();FileInputStream fis = null;try {fis = new FileInputStream("jdbc.properties");pro.load(fis);String name = pro.getProperty("name");String pwd = pro.getProperty("password");System.out.println("name = " + name + ", password = " + pwd);} catch (IOException e) {e.printStackTrace();}finally {if(fis != null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }
name=biggy password=962469
11.HashMap、TreeMap、Hashtable三者的区别
- HashMap:作为Map的主要实现类;线程不安全,但效率高;能够存储null值的key和value;底层在JDK1.7采用数组+链表,JDK1.8采用数组+链表+红黑树
- TreeMap:保证按照添加键值对的顺序进行排序,实现排序遍历;底层的比较不使用equals()方法和hashCode()方法,而是实现Comparable接口中的compareTo(Object obj)方法,或实现Comparator中的compare(Object o1, Object o2)方法。
- Hashtable:作为古老的Map实现类,虽然线程安全,但是效率低;不能存储null值的key和value
12.Collections工具类
-
类似于Arrays工具类,Collections是一个操作List、Set和Map等集合的工具类
-
Collections中提供了一系列的静态方法,这些方法可以对集合元素进行排序、查询、和修改等操作
-
常用操作:
-
排序操作(均为static):
- reverse(List):反转List中的元素
- shuffle(List):对List集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定List集合元素按升序排列
- sort(List, Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序
- swap(List, int i, int j):将指定List集合中的i处元素和j处元素进行交换
-
查找、替换
- Object max(Collection):根据元素的自然排序,返回指定集合中最大的元素
- Object min(Collection):根据元素的自然排序,返回指定集合中最小的元素
- Object max(Collection, Comparator):根据Comparator指定的顺序,返回给定集合中最大的元素
- Object min(Collection, Comparator):根据Comparator指定的顺序,返回给定集合中最小的元素
- int frequency(Collection, Object):返回指定集合中指定元素出现的频率(次数)
- void copy(List dest, List src):将src中的内容复制到dest中
- boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象中所有的旧值
-
同步控制
- Collections类中提供了多个synchronizedXxx()方法,该方法可以将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题(ArrayList、LinkedArrayList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等)
import org.junit.Test;import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List;/*** @Author: xuehai.XUE* @MailBox: xuehai.xue@qq* @Date: 2021/3/23 20:58* @Description:*/ public class CollectionsTest {@Testpublic void test(){List list = new ArrayList();list.add(123);list.add(451);list.add(485);list.add(0);list.add(-516);list.add(98);System.out.println(list);//报异常:java.lang.IndexOutOfBoundsException: Source does not fit in dest // List dest = new ArrayList();//正确写法:创建相同长度的null值List destList dest = Arrays.asList(new Object[list.size()]);System.out.println(dest);Collections.copy(dest, list);System.out.println(dest);//返回的list1即为线程安全的listList list1 = Collections.synchronizedList(list);} }
-
STAY ANGER!!!
更多推荐
20210323Java集合
发布评论