兰州专业网站建设公司哪家好,软件开发项目预算,上海网站建设品牌,自己做网站能做付费链接吗文章目录 1.Map接口概述1.1 Map的实现类的结构1.2 Map中存储的key-value结构的理解1.3 HashMap的底层实现原理(以JDK7为例)1.4 Map接口的常用方法1.5 TreeMap1.6 Map实现类之五: Properties 1.Collections工具类1.1方法1.1.1 排序操作(均为static方法)1.1.2 查找、替换 1.Map接… 文章目录 1.Map接口概述1.1 Map的实现类的结构1.2 Map中存储的key-value结构的理解1.3 HashMap的底层实现原理(以JDK7为例)1.4 Map接口的常用方法1.5 TreeMap1.6 Map实现类之五: Properties 1.Collections工具类1.1方法1.1.1 排序操作(均为static方法)1.1.2 查找、替换 1.Map接口概述
1.1 Map的实现类的结构 /---Map:双列数据存储key-value对的数据类似于高中的函数yf(x)/---HashMap:作为Map的主要实现类线程不安全的效率高可以存储null的key和value/----LinkedHashMap保证在遍历map元素时可以按照添加的顺序实现遍历对于频繁的遍历操作此类执行效率高于HashMap因为在原有的HashMap底层结构基础上添加了一对指针指向前一个和后一个元素/----TreeMap:可以按照添加的key-value对进行排序实现排序遍历此时是按照key进行自然排序和定制排序底层使用的红黑树/----Hashtable:作为Map的古老实现类线程安全的效率低不能存储null的key和value/----Properties常用来处理配置文件。key和value都是String类型HashMap的底层数组链表(jdk7及之前)数组链表红黑树(jdk8及以后面试题
1.HashMap的底层实现原理
2.HashMap和Hashtable的区别
3.CurrentHashMap和HashTable的区别(暂时不讲)
1.2 Map中存储的key-value结构的理解
Map中的key无序的、不可重复的使用set存储所有的key–如果要往Map中存放自定义的类的对象key所在的类要重写equals()和hashCode()方法(以HashMap为例)Map中的value无序的、可重复的使用Collection存储所有的value–value所在的类要重写equals()一个键值对key-value构成了一个Entry对象
要求 1.3 HashMap的底层实现原理(以JDK7为例)
HashMap map new HashMap():
在实例化以后底层创建了长度是16的一维数组Entry[] table.
...可能已经执行过多次put...
map.put(key1,value1):
首先调用key1所在类的HashCode()方法计算key1的哈希值此哈希值经过某种算法计算以后得到在Entry数组中的存放位置。如果此位置上的数据为空此时的key1-value1添加成功。---情况1如果此位置上的数据不为空意味着此位之上存在一个或多个以链表形式存在数据比较key1和已经存在的一个或多个数据的哈希值如果key1的哈希值与已经存在的数据的哈希值都不相同此时的key1-value1添加成功。---情况2如果key1的哈希值和已经存在的某一个数据的哈希值相同继续比较调用key1所在类的equals()方法比较如果equals()返回false此时的key1-value1添加成功。---情况3如果equals()返回true此时使用value1替换value2补充关于情况2和情况3此时key1-value1和原来的数据以链表的方式存储
在不断地添加过程中会涉及到扩容问题默认扩容为原来容量的2倍并将原有的数据复制过来
JDK8与JDK7在底层实现方面的不同
1. new HashMap():底层没有创建一个长度为16的数组
2. JDK8的底层数组是: Node[],而非Entry[]
3. 首次调用put()方法时底层创建长度为16的数组
4. jdk7底层结构只有数组链表。jdk8中底层结构数组链表红黑树。当数组的某一个索引位置上的元素以链表形式存在的数据个数 8 且当前数组的长度 64时
此时此索引位置上的所有数据改为使用红黑树存储(遍历效率高)
4.1 形成链表时七上八下(JDK7:新的元素指向旧的元素即头插。jdk8旧的元素指向新的元素即尾插)面试题:负载因子值的大小,对HashMap有什么影响 负教因子的大小决定了HashMap的数据密度。 负载因子越小就越容易触发扩容数据密度也越小意味着发生碰撞的几率越小数组中的链表也就越短查询和插入时比较的次数也越小性能会更高。但是会浪费一定的内容空间。而且经常扩容也会影响性能建议初始化预设大一点的空间。 按照其他语言的参考及研究经验会考虑将负载因子设置为0.7~0.75此时平均检索长度接近于常数。
1.4 Map接口的常用方法
1.简单的添加、删除、比较等方法
import java.util.*;public class Test {public static void main(String[] args) {HashMap map new HashMap();//1. 添加Object put(Object key, Object value):将制定key-value添加到(或修改)当前map对象map.put(AA,123);map.put(45,123);map.put(BB,56);//2. 修改map.put(AA,87);System.out.println(map);//{AA87, BB56, 45123}HashMap map1 new HashMap();map1.put(CC, 123);//void putAll(Map m):将m中的所有key-value对存放到当前map中map.putAll(map1);System.out.println(map);//{AA87, BB56, CC123, 45123}//3. 删除Object remove(Object key):移除指定key的key-value对并返回valueObject o map.remove(CC);System.out.println(o);//123System.out.println(map);//{AA87, BB56, 45123}//4. 清空void clear(map)清空当前map中的数据map1.clear();System.out.println(map1);//{}//5. Object get(Object key):获取指定key的value值,如果key不存在则返回nullObject o1 map.get(45);System.out.println(o1);//123//6. boolean containsKey(Object key):是否包含指定的keySystem.out.println(map.containsKey(AA));//true//7. boolean containsValue(Object value):是否包含指定的value如果有两个相同的value只要找到一个就返回trueSystem.out.println(map.containsValue(456));//false//8. int size():返回map中key-value对的个数System.out.println(map.size());//3//9. boolean isEmpty():判断当前map是否为空System.out.println(map.isEmpty());//false//10. boolean equals(Object obj): 判断当前map和参数对象obj是否相等System.out.println(map.equals(o1));//false,两个同样的map里边的key和value也都一样比较结果即为true}}
map的遍历(keySet()、values()、entrySet())可以取出每个key和value
package junit;
import org.junit.jupiter.api.Test;import java.sql.SQLOutput;
import java.util.*;public class Test01 {Testpublic void test(){HashMapObject,Object map new HashMap();map.put(AA,123);map.put(45,123);map.put(BB,56);//1. 遍历所有的key集keySet()SetObject set map.keySet();IteratorObject ite set.iterator();while (ite.hasNext()){System.out.println(ite.next());}//2.遍历所有的value集values()CollectionObject coll map.values();for (Object obj: coll) {System.out.println(obj);}//此处可以使用增强for循环或者迭代器//3. 遍历所有的key-value 方法1(用entrySet()方法)Set set1 map.entrySet();Iterator iterator set1.iterator();while (iterator.hasNext()){Object obj iterator.next();Map.Entry entry (Map.Entry)obj;//将Object类型强转为entry类型为了使用get方法System.out.println(entry.getKey() entry.getValue());}//4. 遍历所有的key-value 方法2(先使用keySet()方法得到key然后用map.get()方法)SetObject set2 map.keySet();IteratorObject ite1 set2.iterator();//set是所有key的集合while (ite1.hasNext()){Object key ite1.next();//得到每一个keyObject value map.get(key);//调用get方法得到每一个key对应的valueSystem.out.println(key -- value);}}
}1.5 TreeMap
向TreeMap中添加key-value要求key必须是由同一个类创建的对象,因为要按照key进行排序排序自然排序、定制排序
1.6 Map实现类之五: Properties
Properties类是Hashtable 的子类该对象用于处理属性文件由于属性文件里的 key、value 都是字符串类型所以 Properties里的 key和l value都是字符串类型存取数据时建议使用setProperty(String key,String value)方法和getProperty(String key)方法
public class Test01 {Testpublic void test(){Properties pros new Properties();pros.load(new FileInputStream(jdbc.properties));string user pros.getProperty(user);System.out.println(user);}}
}代码示例
1.Collections工具类
Collections是一个操作Collection和Map等集合的工具类操作数组的工具类为ArraysCollections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作还提供了对集合对象设置不可变、对集合对象实现同步控制等方法Collection和Collections的区别Collection是存储单列数据的集合接口用来存储一个个对象Collections是一个操作Collection和Map等集合的工具类
1.1方法
1.1.1 排序操作(均为static方法)
reverse(List):反转List中元素的顺序shuffle(List):对List集合元紊进行随机排序sort(List):根据元素的自然顺序对指定List集合元紊按升序排序sort(ListComparator):根据指定的Comparator产生的顺序对List集合元素进行排序swap(Listintint):将指定list集合中的i处元素和j处元素进行交换
1.1.2 查找、替换
Object max(Collection):根据元索的自然顺序返回给定集合中的最大元素Object max(CollectionComparator):根据Comparator指定的顺序返回给定集合中的最大元素Object min(Collection)Object min(CollectionComparator)int frequency(Collection,Object):返回指定集合中指定元素的出现次数void copy(List dest,List src):将src中的内容复制到dest中boolean replaceAll(List listObject oldValObject newVal):使用新值替换List对象的所有旧值
package junit;
import org.junit.jupiter.api.Test;import java.io.FileInputStream;
import java.util.*;public class Test01 {Testpublic void test(){ArrayListInteger list new ArrayList();list.add(123);list.add(45);list.add(765);list.add(-97);list.add(0);System.out.println(list);//[123, 45, 765, -97, 0]//1. reverse(List):反转List中元素的顺序Collections.reverse(list);System.out.println(list);//[0, -97, 765, 45, 123]//2.shuffle(List):对List集合元紊进行随机排序Collections.shuffle(list);System.out.println(list);//每次执行后的顺序不同//3.sort(List):根据元素的自然顺序对指定List集合元紊按升序排序Collections.sort(list);System.out.println(list);//[-97, 0, 45, 123, 765]//4.swap(Listintint):将指定list集合中的i处元素和j处元素进行交换Collections.swap(list,1,2);System.out.println(list);//[-97, 45, 0, 123, 765]//5.int frequency(Collection,Object):返回指定集合中指定元素的出现次数list.add(765);int frequency Collections.frequency(list, 765);System.out.println(frequency);//2//6. void copy(List dest,List src):将src中的内容复制到dest中
// ArrayListInteger dest new ArrayList();
// Collections.copy(dest,list);//报异常:IndexOutofBoundsException(source does not fit in dest),因为copy会先比较dest和list的size//正确的List dest1 Arrays.asList(new Object[list.size()]);//new一个长度为list.size()的数组System.out.println(dest1);//[null, null, null, null, null, null]Collections.copy(dest1,list);System.out.println(dest1);//[-97, 45, 0, 123, 765, 765]//collections类中提供了多个synchronizedXxx()方法该方法可使将指定集合包装成线程同步的集合从而可以解决多线程并发访问集合时的线程安全问题//返回的List1即为线程安全的ListList list1 Collections.synchronizedList(list);}}