------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Map 接口
Map 接口定义的集合,又称查找表
Map 接口和 Collection 接口没关系
Map 集合派系,存储映射键值对
不允许重复的键,每个键最多映射 1 个值
根据内部数据结构不同,Map 接口有多种实现类:
常用的有内部为 hash 表实现的 HashMap 和内部为排序二叉树实现的 TreeMap
Map 接口和 Collection 接口的不同
Map 和 Collection 是独立的接口
Map 双列,存储键值对映射关系,键具有唯一性,每个键只能映射 1 个值
Collection 单列,存储对象的引用,其 Set 子接口的元素是唯一的
Map 的数据结构只针对键有效,跟值无关;Collection 的数据结构针对元素有效
Map 接口成员方法
V put(K key, V value)
// 将键值对存储到集合,返回值一般是 null,存储重复键返回被替换之前的值
V get(Object key) // 根据键获取值,如果不存在返回 null
V remove(Object key) // 移除指定键的映射关系,返回该键对应的值
void clear() // 清空集合
boolean containsKey(Object key) // 判断是否包含指定键的映射关系
boolean containsValue(Object value) // 判断是否包含指定值
boolean isEmpty() // 判断是否为空
int size() // 返回集合大小
Set<K> keySet() // 将 Map 集合中所有的键,存储到 Set 集合
Collection<V> values() // 将 Map 集合中的所有值,存储到 Collection 集合
Set<Map.Entry<K, V>> entrySet() // 将所有键值对存储到集合
Map 集合遍历
第一种方式 Set<K> keySet():适合开发使用,简单、代码量少
Map 接口中定义的方法keySet,将 Map 集合中所有的键存储到 Set 集合,迭代 Set 集合,获取出 Set 集合中存储的元素就是 Map 中的键,get() 根据键获取值。
- 1. 调用 Map 集合方法 keySet,将所有键存储到集合
- 2. 迭代 Set 集合,获取 Set 集合存储的对象
- 3. Map 集合方法 get,传递键获取值
Set<String>set= map.keySet();
Iterator<String>iterator= set.iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
Integer value = map.get(key);
System.out.println("value= " + value);
}
第二种方式Set<Map.Entry<K, V>> entrySet():适合面试考试
原理:存储键值对,键值对的映射关系也是一个对象,对象的描述是接口,是 Map 接口的内部接口 Entry 。Map 集合中,实现了这个内部接口 Entry,重写接口中的方法,可以让我们获取 Map 集合中的键值对。
Entry 的方法:K getKey(), V getValue()
- 1. 调用 Map 集合方法 entrySet,将所有键值对映射关系对象(即 Map.Entry 接口的实现类对象)存储到 Set 集合
- 2. 迭代 Set 集合,获取 Set 集合存储的对象(Map.Entry 接口的实现类对象)
- 3. 调用 Map.Entry 接口的方法 getKey, getValue 分别获取键和值
Set<Map.Entry<String,Integer>> set2= map.entrySet();
Iterator<Map.Entry<String,Integer>> iterator2= set2.iterator();
while (iterator2.hasNext()) {
Map.Entry<String, Integer> entry = (Map.Entry<String,Integer>) iterator2.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("key= " + key + ", value= "+ value);
}
增强 for 循环遍历示例
package cn.itcast;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/*
* Map 接口和Iterable 没有关系不具有获取迭代器方法,
* 增强for不能直接遍历Map集合
* 但是可以间接遍历(遍历的是Set)
*/
public class MapForEach {
publicstatic void main(String[] args) {
Map<String,Integer> map = new HashMap<String, Integer>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
Set<String>set = map.keySet();
for(String key : set) {
Integervalue = map.get(key);
System.out.println("value=" + value);
}
System.out.println("-------------------");
Set<Map.Entry<String,Integer>> set2 = map.entrySet();
for(Entry<String, Integer> entry : set2) {
Stringkey = entry.getKey();
Integervalue = entry.getValue();
System.out.println("key=" + key + ", value= " + value);
}
}
}
HashMap 类
底层数据结构,键是哈希表结构,保证键的唯一性
(存储自定义对象的键,需要重写 hashCode equals 方法)
允许存储 null 键值
存储速度快,线程不安全集合,运行速度快
LinkedHashMap 类继承 HashMap
基于链表和哈希表的实现,线程不安全集合
维护着一个双向循环链表,此链表定义了迭代顺序,通常是存放元素的顺序
有序 Map 集合,存储取出的顺序一致,具有可预知的迭代顺序
TreeMap 类
底层数据结构是红黑树(保证键的排序和唯一性)
对存储的键进行排序,自然排序和比较器排序
线程不安全集合运行速度快
- 获取字符串中每个字母出现的次数
package cn.itcast;
import java.util.TreeMap;
/*
* 统计字符串中每个字母出现的次数
*
* 思路:
* 将字符串转成字符数组,遍历字符数组,
* 将每个字母及其出现的次数存进 Map 集合
* 遍历存储集合完成后,取出集合中的键值
*/
publicclassTreeMapTest {
publicstaticvoid main(String[] args) {
Stringstring= "wwwitcastcn";
// Map 集合存储字母及其出现的次数
TreeMap<Character,Integer> map= newTreeMap<Character, Integer>();
char[] arr = string.toCharArray();
for (charc : arr) {
// 获取字母已出现的次数并根据当前迭代情况修改
Integervalue= map.get(c);
if (value == null) {
map.put(c, 1);
}else{
map.put(c, ++value);
}
}
// 遍历集合中存储的键(即每个字母),获取相应的值(即字母出现的次数)
for (charkey : map.keySet()) {
Integervalue= map.get(key);
System.out.println(key + "(" + value + ")");
}
}
}
Hashtable 集合自身特性
底层数据结构是哈希表,保证键的唯一性
不允许存储 null 键值
线程安全集合,运行速度慢
Properties 类继承 Hashtable
底层数据结构是哈希表,线程安全集合
可以和IO流结合使用,实现数据持久性存储
存储和取出的代码和HashMap 完全一样
为什么没有泛型?固定集合存储的类型,属性列表中每个键、值都是字符串
setProperty(String key, String value) // 将键值对存储到集合
String getProperty(String key) // 根据键获取值
HashMap 和 Hashtable 的区别
二者都实现了 Map 接口,是将唯一键映射到特定的值上
HashMap:
线程不安全,运行速度快
没有排序,可以存储 null 键和多个 null 值
Hashtable:
线程安全,运行速度慢
不可以存储 null 键值
List, Set, Map 等接口是否都继承自 Collection 接口
List 和 Set 继承自 Collection接口,而 Map 不继承任何接口
java.util.Collections 类,集合操作的工具类
// 对集合中的元素进行自然顺序排序
//对自定义对象排序需要在类中实现 Coparable 接口并重写 compareTo 方法
Collections.sort(list);
// 返回一个比较器对象,逆转对象的自然顺序
Comparator<String>comparator= Collections.reverseOrder();
Collections.sort(list, comparator);
// 对集合中的元素的顺序进行反转
Collections.reverse(list);
// 二分法查找在集合中指定元素返回索引值
intindex = Collections.binarySearch(list, "itcast");
// 对集合中的元素随机排列
Collections.shuffle(list);
- Sting[] <-->List
String[] strArr = {"www", ".itcat",".cn"};
List<String> list = Arrays.asList(strArr); // fixed-sizelist
for(String string : list) {
System.out.print(string + " "); // www .itcast .cn
}
// list.add(""); // UnsupportedOperationException
// java.util.Arrays$ArrayList
System.out.println(list.getClass().getName());
list.set(0, "3w"); // 可以修改元素
// 如果想要添加元素,可以用如下方式:
List<String> list1 = new ArrayList<String>();
list1.addAll(list);
System.out.println(list1); // [www, .itcast, .cn]
list1.add("0807JavaSE");
System.out.println(list1); // [www, .itcast, .cn, 0807JavaSE]