a.
Map
概述
* util包下,是双列集合的根接口,即方法都是抽象的
* 表现形式是一个<K,V> 的一种映射关系,即一一对应的关系
* K -- 此映射所维护键的类型
* V -- 映射值的类型
* 将键映射到值的对象
* 一个映射不能包含重复的键
* 每个键最多只能映射到一个值
* 存取无序 --LinkedHashMap除外
Map与Collection接口的不同
* Map是双列集合的根接口,Collection是单列集合的根接口
* Map是键唯一,Collection的子体系中Set是唯一 --map集合和Collection的子体系的set集合很像。
* HashSet底层依赖的是map,二者底层都是哈希算法
* Map集合的数据结构是值针对键有效,与值无关
* Collection集合的数据结构是针对元素有效
b.
Map集合的功能
概述
* 添加功能
* V put(K key, V value); 添加元素
* 如果键是第一次存储,那就直接存储元素,返回null
* 如果键不是第一次存在,就用值代替原来的值,返回原来的值
* 删除功能
* void clear(); 移除所有的键值对元素
* V remove(Object key); 根据键删除值,并将值返回
* 判断功能
* boolean containsKey(Object key); 判断集合是否包含指定键
* boolean containsKey(Object value); 判断集合是否包含指定值
* boolean isEmpty(); 判断该集合是否为空
* 获取功能
* Set<Map.Entry<K,V>> entrySet();
* V get(Object key); 根据键获取值
* Set<K> keySet(); 获取集合中所有键的集合
* Collection<V> values(); 获取集合中所有值的集合
* 长度功能
* int size(); 返回集合中的键值对的个数
c.
Map集合的遍历
概述
* 通过查询map集合的API发现没有Iterator的方法,那么双列集合该怎么遍历获取到元素呢?
* map集合的遍历不能直接使用迭代器来完成。
* map集合的遍历分为两种
* --键找值
* 思路
* 获取所有键的集合
* 使用遍历set集合的迭代器方式遍历键集合
* 遍历键的集合,获取到每一个键
* 根据键找值
* 方式1 --使用迭代器
Set<String> keySet = map.keySet();
Iterator ir = keySet.iterator();
while(ir.hasNext){ //判断是否还有下一个键
String key = ir.next(); //获取所有的键
Integer value = map.get(key); //通过键找值
}
* 方式2 --使用增强for
for(String key : map.keySet()){ //获取所有的键的集合
Integer value = map.get(key); //通过键获取值
System.out.println(key+"..."+value);
}
* --键值对对象找键和值
* 思路
* 获取所有键值对对象的集合 --Map.Entry<String, Integer>键值对对象
* 遍历键值对对象的集合,获取到每一个键值对对象
* 根据键值对对象找键和值
* 过程:
(将双列集合的键值对变成单列集合的键值对对象,然后遍历这个集合获取到每一个键值对对象,根据键值对对象获取到键和值)
* 注意:
Set<Map.Entry<String, Integer>>
Map.Entry说明Entry是map的内部接口,将键和值封装成了Entry对象,并且存储到了Set集合中去
这里的Map.Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap)
而Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap) 表示直接获取子类对象(子类对象:HashMap)
* 方式1 --通过键值对对象集合遍历迭代器的方式获取到键和值
//Set<Map.Entry<String,Integer>> entrySet = map.entrySet(); //父类引用指向子类对象(HashMap)
Set<Entry<String,Integer>> entrySet = map.entrySet(); //直接获取子类对象 获取所有键值对对象的集合
Iterator<Entry<String, Integer>> ir = entrySet.iterator(); //通过迭代器来遍历所有键值对对象
while(ir.hasNext()){ //判断是否还有下一个键值对对象
Entry<String, Integer> en = ir.next(); //获取到键值对对象
String key = en.getKey(); //通过键值对对象获取到键
Integer value = en.getValue(); //通过键值对对象获取到值
System.out.println(key+"..."+value);
}
* 方式2 --通过增强for的方式获取到所有键值对对象的键和值
for (Entry<String, Integer> en : map.entrySet()) {
String key = en.getKey();
Integer value = en.getValue();
System.out.println(key+"..."+value);
}
d.
HashMap集合键是Student值是String的案例
* 案例演示
* HashMap集合键是Student值是String的案例
* 分析
* 键是学生基类对象
* 值是学生的归属地
* 前提:基类必须重写hashCode和equals方法,和HashSet的理论一致。
e.
LinkedHashMap
概述
* util包下,是个类对象
* 底层链表结构实现,所以保证了怎么存怎么取。又因为是HashMap的子类对象,所以同样保证了键的唯一性
使用
* 代码实现
f.
TreeMap
概述
* util包下,是一个类对象
* 基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序Comparable进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
使用
* 案例演示
* TreeMap集合键是Student值是String的案例
* 代码
* demo01_TreeSet使用自然排序的方式对进行进行_升序_排序();
* demo02_TreeSet使用比较器排序的方式对元素进行_降序_排序();
【自然排序的compare方法 和 比较器的compareTo方法 类似于hashcode和equals的比较顺序,都是先比较第一个方法,如果第一个方法条件不成立,就比较第二个方法,如果第一个方法条件成立,就无需比较第二个方法。提高了代码的运行效率】
【当自然排序和比较器排序都存在时,系统会优先以 比较器排序为准。】
g.
统计字符串中每个字符出现的次数
* 案例演示
* 需求:键盘录入字符串,统计字符串中每个字符出现的次数
集合嵌套之HashMap嵌套HashMap
h.
【面试题--在企业面试过程中JavaEE要占整个面试的60%~70%】
HashMap和Hashtable的区别
概述
* Hashtable是jdk1.0时出现,当集合体系在jdk1.2版本出现后,让Hashtable也实现了Map接口。成为了Map集合体系中的一部分,但是该Hashable是线程安全的,同步(加
*
*
*
*
*
*
* ),执行效率低,所以被jdk1.2后map集合体系中的HashMap给替代掉了。因为HashMap是线程不安全的,执行效率高。 --整个过程类似List集合系统中的Vector一样的命运。
区别
* 共同点:
* 底层都是 哈希算法,都是双列集合。
* 异同点:
1. * HashMap是线程不安全的,执行效率高,jdk1.2版本时候出现。
* Hashtable是线程安全的,执行效率低,jdk1.0版本时候出现。
2. * HashMap可以存储Null键,Null值。
* Hashable不可以存储Null键,Null值。
i.
Collections工具类的概述和常见方法
Collections工具类的概述和常见方法
概述
* Collections是针对集合操作的 工具类。
* 查看API可知,所有方法都是静态的,所以要做一步操作:
* 当一个类中所有方法都是静态的,要私有构造方法,目的是不让其他类去创建本类对象,而是直接 类名.方法名 调用即可。
成员方法
* public static <T> void sort(List<T> list); 根据元素的自然顺序 对指定列表按升序进行排序。
* public static <T> int binarySearch(List<T> list, T key); 使用二分搜索法搜索指定列表,以获得指定对象。
* 如果该元素不存在,就返回 该元素在集合的正序排序的负的插入点-1即:
* public static <T> T max(Collection<?> coll); 根据元素的自然顺序,返回给定 collection 的最大元素。
* public static void reverse(List<T> list); 反转指定列表中元素的顺序。
* public static void shuffle(List<T> list); 使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
* 如:对扑克牌随机洗牌,即元素排序的顺序每次不同
g.
模拟斗地主洗牌和发牌
案例演示
* 模拟斗地主洗牌和发牌,牌没有排序
案例演示
* 模拟斗地主洗牌和发牌并对牌进行排序的代码实现
k.
泛型固定下边界
? super E --固定下边界
向上限定,此时的? 只能够是E或E的父类 --只能够是BaseStudent或BaseStudent的父类
* 比如:TreeSet(Comparator<? super E> comparator) 比较器排序
? extends E --这种写法叫:固定上边界。
向下限定,此时的? 只能够是E或E的子类 --只能够是Student或Student的子类
* 比如:ArrayList 的 addAll(Collection<? extends E> c) 添加集合的方法
【集合继承体系图】
Collection 单列集合顶层接口
* List 存取有序,有索引,元素可重复。
* ArrayList
* 底层:数组结构实现。线程不安全,不同步,所以执行效率高。查询快,修改快,增删慢。
* Vector
* 底层:数组结构实现。线程安全,同步,所以执行效率低。增删改查都慢。jdk1.0时出现,在jdk1.2时候并入集合体系。已被ArrayList替代。
* LinkedList
* 底层:链表结构实现。线程不安全,不同步,所以执行效率高。查询慢,修改慢。增删快。
查询多,修改多,用ArrayList
增加多,删除多,用LinkedList
都多,用ArrayList
* Set 存取无序,无索引,元素不可重复。
* HashSet
* 底层:哈希算法实现。线程不安全,不同步。所以执行效率高。
* 存储自定义Bean对象,保证元素的唯一性,必须依赖hashcode和equals方法。
* LinkedHashSet
* 底层:链表结构实现。是Set集合中唯一一个存取有序的集合,又因为是HashSet的子类,所以保证了元素的唯一性。
* TreeSet
* 底层:二叉树实现。线程不安全,不同步。所以执行效率高。
* TreeSet是用做排序的。依赖的是 自然排序 和 比较器排序。
开发过程中,不需要对存储元素排序,大多时候用HashSet,因为HashSet效率高。
TreeSet在面试时候比较多:问有几种排序方式 和 几种排序方式的区别
* 方式:自然排序 和 比较器排序
* 区别:
* 自然排序:Bean类实现comparable接口,重写compareTo方法,new TreeSet集合对象是什么都不传入。
* 比较器排序:在new TreeSet集合对象时,传入使用匿名内部类的方式,传入比较器接口,重写compare()方法。
Map 双列集合顶层接口 表现形式是一种 <K,V>的映射关系
* HashMap
* 底层:哈希算法实现。线程不安全,不同步。针对键。
* linkedHashMap
* 底层:链表结构实现。线程不安全,不同步。是HashMap的子类。针对键。
* TreeMap
* 底层:二叉树实现。线程不安全,不同步。 对元素进行排序的。 该映射根据 自然排序 和 比较器排序。
* Hashtable
* 底层:哈希算法。是jdk1.0时候出现,在jdk1.2时候并入集合体系。已被HashMap替代。
Map是键唯一,Collection的子体系中Set是唯一 --map集合和Collection的子体系的set集合很像。
单列集合存储重复元素,优先考虑ArrayList, 如果不存储重复元素,优先考虑HashSet
双列集合自己考虑用HashMap,如果要对 键 进行排序,使用TreeSet。
【集合的遍历方式】
Collection
1. 普通for,配合size()和get(int index)使用。
2. toArray集合转数组后,配合普通for或增强for。
3. 迭代器Iterator 不能边遍历元素,边修改(增加)元素,但必须使用自己迭代器remove()的方法。
4. List特有迭代器ListIterator。可以边遍历元素,边修改(增加,删除)元素,但必须使用自己迭代器add()的方法。
5. 增强for。
6. Vector自己特有的遍历方式:Vector vec = new Vector(); Enumeration ele = vec.elements(); 获取枚举的方式。
Map
1. keySet()
2. entrySet()
Map
概述
* util包下,是双列集合的根接口,即方法都是抽象的
* 表现形式是一个<K,V> 的一种映射关系,即一一对应的关系
* K -- 此映射所维护键的类型
* V -- 映射值的类型
* 将键映射到值的对象
* 一个映射不能包含重复的键
* 每个键最多只能映射到一个值
* 存取无序 --LinkedHashMap除外
Map与Collection接口的不同
* Map是双列集合的根接口,Collection是单列集合的根接口
* Map是键唯一,Collection的子体系中Set是唯一 --map集合和Collection的子体系的set集合很像。
* HashSet底层依赖的是map,二者底层都是哈希算法
* Map集合的数据结构是值针对键有效,与值无关
* Collection集合的数据结构是针对元素有效
b.
Map集合的功能
概述
* 添加功能
* V put(K key, V value); 添加元素
* 如果键是第一次存储,那就直接存储元素,返回null
* 如果键不是第一次存在,就用值代替原来的值,返回原来的值
* 删除功能
* void clear(); 移除所有的键值对元素
* V remove(Object key); 根据键删除值,并将值返回
* 判断功能
* boolean containsKey(Object key); 判断集合是否包含指定键
* boolean containsKey(Object value); 判断集合是否包含指定值
* boolean isEmpty(); 判断该集合是否为空
* 获取功能
* Set<Map.Entry<K,V>> entrySet();
* V get(Object key); 根据键获取值
* Set<K> keySet(); 获取集合中所有键的集合
* Collection<V> values(); 获取集合中所有值的集合
* 长度功能
* int size(); 返回集合中的键值对的个数
c.
Map集合的遍历
概述
* 通过查询map集合的API发现没有Iterator的方法,那么双列集合该怎么遍历获取到元素呢?
* map集合的遍历不能直接使用迭代器来完成。
* map集合的遍历分为两种
* --键找值
* 思路
* 获取所有键的集合
* 使用遍历set集合的迭代器方式遍历键集合
* 遍历键的集合,获取到每一个键
* 根据键找值
* 方式1 --使用迭代器
Set<String> keySet = map.keySet();
Iterator ir = keySet.iterator();
while(ir.hasNext){ //判断是否还有下一个键
String key = ir.next(); //获取所有的键
Integer value = map.get(key); //通过键找值
}
* 方式2 --使用增强for
for(String key : map.keySet()){ //获取所有的键的集合
Integer value = map.get(key); //通过键获取值
System.out.println(key+"..."+value);
}
* --键值对对象找键和值
* 思路
* 获取所有键值对对象的集合 --Map.Entry<String, Integer>键值对对象
* 遍历键值对对象的集合,获取到每一个键值对对象
* 根据键值对对象找键和值
* 过程:
(将双列集合的键值对变成单列集合的键值对对象,然后遍历这个集合获取到每一个键值对对象,根据键值对对象获取到键和值)
* 注意:
Set<Map.Entry<String, Integer>>
Map.Entry说明Entry是map的内部接口,将键和值封装成了Entry对象,并且存储到了Set集合中去
这里的Map.Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap)
而Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap) 表示直接获取子类对象(子类对象:HashMap)
* 方式1 --通过键值对对象集合遍历迭代器的方式获取到键和值
//Set<Map.Entry<String,Integer>> entrySet = map.entrySet(); //父类引用指向子类对象(HashMap)
Set<Entry<String,Integer>> entrySet = map.entrySet(); //直接获取子类对象 获取所有键值对对象的集合
Iterator<Entry<String, Integer>> ir = entrySet.iterator(); //通过迭代器来遍历所有键值对对象
while(ir.hasNext()){ //判断是否还有下一个键值对对象
Entry<String, Integer> en = ir.next(); //获取到键值对对象
String key = en.getKey(); //通过键值对对象获取到键
Integer value = en.getValue(); //通过键值对对象获取到值
System.out.println(key+"..."+value);
}
* 方式2 --通过增强for的方式获取到所有键值对对象的键和值
for (Entry<String, Integer> en : map.entrySet()) {
String key = en.getKey();
Integer value = en.getValue();
System.out.println(key+"..."+value);
}
d.
HashMap集合键是Student值是String的案例
* 案例演示
* HashMap集合键是Student值是String的案例
* 分析
* 键是学生基类对象
* 值是学生的归属地
* 前提:基类必须重写hashCode和equals方法,和HashSet的理论一致。
e.
LinkedHashMap
概述
* util包下,是个类对象
* 底层链表结构实现,所以保证了怎么存怎么取。又因为是HashMap的子类对象,所以同样保证了键的唯一性
使用
* 代码实现
f.
TreeMap
概述
* util包下,是一个类对象
* 基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序Comparable进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
使用
* 案例演示
* TreeMap集合键是Student值是String的案例
* 代码
* demo01_TreeSet使用自然排序的方式对进行进行_升序_排序();
* demo02_TreeSet使用比较器排序的方式对元素进行_降序_排序();
【自然排序的compare方法 和 比较器的compareTo方法 类似于hashcode和equals的比较顺序,都是先比较第一个方法,如果第一个方法条件不成立,就比较第二个方法,如果第一个方法条件成立,就无需比较第二个方法。提高了代码的运行效率】
【当自然排序和比较器排序都存在时,系统会优先以 比较器排序为准。】
g.
统计字符串中每个字符出现的次数
* 案例演示
* 需求:键盘录入字符串,统计字符串中每个字符出现的次数
集合嵌套之HashMap嵌套HashMap
h.
【面试题--在企业面试过程中JavaEE要占整个面试的60%~70%】
HashMap和Hashtable的区别
概述
* Hashtable是jdk1.0时出现,当集合体系在jdk1.2版本出现后,让Hashtable也实现了Map接口。成为了Map集合体系中的一部分,但是该Hashable是线程安全的,同步(加
*
*
*
*
*
*
* ),执行效率低,所以被jdk1.2后map集合体系中的HashMap给替代掉了。因为HashMap是线程不安全的,执行效率高。 --整个过程类似List集合系统中的Vector一样的命运。
区别
* 共同点:
* 底层都是 哈希算法,都是双列集合。
* 异同点:
1. * HashMap是线程不安全的,执行效率高,jdk1.2版本时候出现。
* Hashtable是线程安全的,执行效率低,jdk1.0版本时候出现。
2. * HashMap可以存储Null键,Null值。
* Hashable不可以存储Null键,Null值。
i.
Collections工具类的概述和常见方法
Collections工具类的概述和常见方法
概述
* Collections是针对集合操作的 工具类。
* 查看API可知,所有方法都是静态的,所以要做一步操作:
* 当一个类中所有方法都是静态的,要私有构造方法,目的是不让其他类去创建本类对象,而是直接 类名.方法名 调用即可。
成员方法
* public static <T> void sort(List<T> list); 根据元素的自然顺序 对指定列表按升序进行排序。
* public static <T> int binarySearch(List<T> list, T key); 使用二分搜索法搜索指定列表,以获得指定对象。
* 如果该元素不存在,就返回 该元素在集合的正序排序的负的插入点-1即:
* public static <T> T max(Collection<?> coll); 根据元素的自然顺序,返回给定 collection 的最大元素。
* public static void reverse(List<T> list); 反转指定列表中元素的顺序。
* public static void shuffle(List<T> list); 使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
* 如:对扑克牌随机洗牌,即元素排序的顺序每次不同
g.
模拟斗地主洗牌和发牌
案例演示
* 模拟斗地主洗牌和发牌,牌没有排序
案例演示
* 模拟斗地主洗牌和发牌并对牌进行排序的代码实现
k.
泛型固定下边界
? super E --固定下边界
向上限定,此时的? 只能够是E或E的父类 --只能够是BaseStudent或BaseStudent的父类
* 比如:TreeSet(Comparator<? super E> comparator) 比较器排序
? extends E --这种写法叫:固定上边界。
向下限定,此时的? 只能够是E或E的子类 --只能够是Student或Student的子类
* 比如:ArrayList 的 addAll(Collection<? extends E> c) 添加集合的方法
【集合继承体系图】
Collection 单列集合顶层接口
* List 存取有序,有索引,元素可重复。
* ArrayList
* 底层:数组结构实现。线程不安全,不同步,所以执行效率高。查询快,修改快,增删慢。
* Vector
* 底层:数组结构实现。线程安全,同步,所以执行效率低。增删改查都慢。jdk1.0时出现,在jdk1.2时候并入集合体系。已被ArrayList替代。
* LinkedList
* 底层:链表结构实现。线程不安全,不同步,所以执行效率高。查询慢,修改慢。增删快。
查询多,修改多,用ArrayList
增加多,删除多,用LinkedList
都多,用ArrayList
* Set 存取无序,无索引,元素不可重复。
* HashSet
* 底层:哈希算法实现。线程不安全,不同步。所以执行效率高。
* 存储自定义Bean对象,保证元素的唯一性,必须依赖hashcode和equals方法。
* LinkedHashSet
* 底层:链表结构实现。是Set集合中唯一一个存取有序的集合,又因为是HashSet的子类,所以保证了元素的唯一性。
* TreeSet
* 底层:二叉树实现。线程不安全,不同步。所以执行效率高。
* TreeSet是用做排序的。依赖的是 自然排序 和 比较器排序。
开发过程中,不需要对存储元素排序,大多时候用HashSet,因为HashSet效率高。
TreeSet在面试时候比较多:问有几种排序方式 和 几种排序方式的区别
* 方式:自然排序 和 比较器排序
* 区别:
* 自然排序:Bean类实现comparable接口,重写compareTo方法,new TreeSet集合对象是什么都不传入。
* 比较器排序:在new TreeSet集合对象时,传入使用匿名内部类的方式,传入比较器接口,重写compare()方法。
Map 双列集合顶层接口 表现形式是一种 <K,V>的映射关系
* HashMap
* 底层:哈希算法实现。线程不安全,不同步。针对键。
* linkedHashMap
* 底层:链表结构实现。线程不安全,不同步。是HashMap的子类。针对键。
* TreeMap
* 底层:二叉树实现。线程不安全,不同步。 对元素进行排序的。 该映射根据 自然排序 和 比较器排序。
* Hashtable
* 底层:哈希算法。是jdk1.0时候出现,在jdk1.2时候并入集合体系。已被HashMap替代。
Map是键唯一,Collection的子体系中Set是唯一 --map集合和Collection的子体系的set集合很像。
单列集合存储重复元素,优先考虑ArrayList, 如果不存储重复元素,优先考虑HashSet
双列集合自己考虑用HashMap,如果要对 键 进行排序,使用TreeSet。
【集合的遍历方式】
Collection
1. 普通for,配合size()和get(int index)使用。
2. toArray集合转数组后,配合普通for或增强for。
3. 迭代器Iterator 不能边遍历元素,边修改(增加)元素,但必须使用自己迭代器remove()的方法。
4. List特有迭代器ListIterator。可以边遍历元素,边修改(增加,删除)元素,但必须使用自己迭代器add()的方法。
5. 增强for。
6. Vector自己特有的遍历方式:Vector vec = new Vector(); Enumeration ele = vec.elements(); 获取枚举的方式。
Map
1. keySet()
2. entrySet()