集合框架
Map集合
java.util.Map
接口,也是集合容器.
Collection集合和Map集合的区别
- Collection集合存储元素,每次只能存储单个的元素
- Map集合存储元素,每次需要存储两个元素
- 一个元素做为键,一个元素做为值
- 一个集合中,键必须保证唯一性
- 一个键只能映射一个值
Map接口的方法
V put(K,V)
将键值对存储到集合中,返回被覆盖之前的值V get(K)
返回键对应的值,集合中没有这个键,返回nullboolean containsKey(K)
判断集合中是否包含此键,包含返回trueboolean containsValue(V)
判断集合中是否包含此值,包含返回trueV remove(K)
移除集合中的键值对,返回被移除之前的值Conllection<V> values()
集合中的所有的值取出,存储到Collection集合
Map集合遍历一
Map的遍历方式 : 键找值方式
Map接口定义方法 : Set keySet() Map集合的键,取出,存储在Set集合
/*
* Map集合方法keySet()遍历
* 步骤:
* 1. Map集合方法keySet()获取 存储键的Set集合
* 2. 遍历Set集合
* 3. 取出Set集合元素,是Map的键
* 4. Map集合键,找值
*/
public class MapDemo02 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 125);
// 1. Map集合方法keySet()获取 存储键的Set集合
Set<String> set = map.keySet();
//2. 遍历Set集合
Iterator<String> it = set.iterator();
while(it.hasNext()) {
//3. 取出Set集合元素,是Map的键
String key = it.next();
//4. Map集合键,找值
Integer value = map.get(key);
System.out.println(key +"==" + value);
}
}
}
Map集合遍历二
键值对的映射关系遍历: Map.Entry接口,实现类对象表示了键值对的对应关系. 拿到Map.Entry接口实现类对象.
- Entry接口的方法
K getKey()
取出集合中的键V getValue()
取出集合中的值
- Map接口定义方法
Set<Entry<K,V>> entrySet()
集合中的键值对映射关系对象,Entry接口对象,存储在Set集合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Ri2u7qL-1595508828109)(images/Map遍历原理.jpg)]
/*
* Map集合遍历, 键值对的映射关系
* 步骤:
* 1: Map集合方法entrySet() 获取到Entry接口实现类对象,存储Set集合
* 2: 遍历Set集合
* 3: 取出Set集合中的元素 , 是Entry接口的实现类对象 (键值对的对应关系)
* 4: Entry接口对象,调用方法getKey(), getValue()
*/
public class MapDemo03 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 125);
//1: Map集合方法entrySet() 获取到Entry接口实现类对象,存储Set集合
Set<Map.Entry<String,Integer> > set = map.entrySet();
//2: 遍历Set集合
Iterator<Map.Entry<String,Integer> > it = set.iterator();
while(it.hasNext()) {
//3: 取出Set集合中的元素 , 是Entry接口的实现类对象 (键值对的对应关系)
Map.Entry<String, Integer> entry = it.next();
//4: Entry接口对象,调用方法getKey(), getValue()
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key +"==" + value);
}
}
}
增强for循环间接遍历Map集合
public static void main(String[] args) {
entry();
}
public static void entry() {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 125);
//Set<Map.Entry<String,Integer> > set = map.entrySet();
for(Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + "==" + entry.getKey());
}
}
public static void keySet() {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 125);
for(String key : map.keySet()) {
//Integer value = map.get(key);
System.out.println(key + "==" + map.get(key));
}
}
HashMap
java.util.HashMap
类,实现Map接口.
- HashMap集合特点
- 底层是哈希表结构, 数组+链表
- 默认长度16,加载因子0.75F
- 保证存储到键对象的唯一性,做为键的对象,必须重写hashCode和equals
- 链表长度到达8个,转成红黑树 (尾查)
- 线程不安全集合,允许速度快
- 集合允许存储null值,null键
/*
* HashMap集合,String做为键, Person对象做为值
*/
public static void method() {
//HashMap集合,String做为键, Person对象做为值
Map<String, Person> map = new HashMap<String, Person>();
map.put("北京市", new Person("张三",20));
map.put("天津市", new Person("李四",21));
map.put("上海市", new Person("王五",22));
map.put("重庆市", new Person("赵六",23));
//keySet方式遍历
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while(it.hasNext()) {
String key = it.next();
Person value = map.get(key);
System.out.println(key+"=="+value);
}
System.out.println("===================");
//entrySet方式遍历
Set<Map.Entry<String, Person>> entSet = map.entrySet();
Iterator<Map.Entry<String, Person>> enIt = entSet.iterator();
while(enIt.hasNext()) {
Map.Entry<String, Person> entry = enIt.next();
String key = entry.getKey();
Person value = entry.getValue();
System.out.println(key+"=="+value);
}
}
/*
* HashMap集合, Person对象做为键, String做为值
*/
public static void method_2() {
//HashMap集合, Person对象做为键, String做为值
Map<Person, String> map = new HashMap<Person, String>();
map.put(new Person("张三",20), "北京市");
map.put(new Person("李四",21), "天津市");
map.put(new Person("李四",21), "东莞市");
map.put(new Person("王五",22), "上海市");
map.put(new Person("赵六",23), "重庆市");
//keySet方式遍历
Set<Person> set = map.keySet();
Iterator<Person> it = set.iterator();
while (it.hasNext()) {
Person key = it.next();
String value = map.get(key);
System.out.println(key+"=="+value);
}
System.out.println("===================");
//entrySet方式遍历
Set<Map.Entry<Person, String>> enSet = map.entrySet();
Iterator<Map.Entry<Person, String>> enIt = enSet.iterator();
while(enIt.hasNext()) {
Map.Entry<Person, String> entry = enIt.next();
Person key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"=="+value);
}
}
LinkedHashMap
java.util.LinkedHashMap
类, 继承HashMap,实现Map接口
java.util.LinkedHashSet
类, 继承HashSet,实现Set接口
- LinkedHashMap集合特点
- 底层数据结构是哈希表, 子类是双向链表
- 集合是有序的集合,存储和取出的顺序一致
- 线程不安全集合,运行速度快
public static void main(String[] args) {
LinkedHashMap<String, String> linked = new LinkedHashMap<String, String>();
linked.put("b", "2");
linked.put("d", "4");
linked.put("a", "1");
linked.put("c", "3");
System.out.println(linked);
}
Hashtable
java.util.Hashtable
类,实现Map接口
- Hashtable集合特点
- 底层是哈希表结构
- 不能存null值,null键 (抛出空指针异常)
- 线程安全的集合,运行速度慢
- 从JDK1.2版本开始,被更加先进的HashMap取代
- Vector集合, List接口实现类
- 线程安全的,可变数组实现
- 从JDK1.2开始,被更加先进的ArrayList取代
Properties
集合框架包括数组,属于临时性数据, 数据在内存中存储.
程序退出了,关机了,数据消失了.
和IO流技术结合,实现数据的持久化.
java.util.Properties
类, 继承Hashtable,实现接口Map
键值对存储的集合, 所有的Map的使用方式,在Properties中全部适用.
没有泛型的集合, 类定义中,没有使用泛型技术.
Properties集合中键值对的数据类型,被锁定为String类型
Properties设计失误的类
不能使用多态,设计存在失误
Properties特有的方法
setProperty(String key,String value)
键值对存储到集合中, setProperty==putString getProperty(String key)
返回指定键对应的值Set<String> stringPropertyNames()
集合的全部键,存储到Set集合
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//存储键值对
prop.setProperty("a", "1");
prop.setProperty("b", "2");
prop.setProperty("c", "3");
System.out.println(prop);
//取出键值对
//String value = prop.getProperty("a");
//System.out.println(value);
//遍历集合, 键存储到Set集合
Set<String> set = prop.stringPropertyNames();
Iterator<String> it = set.iterator();
while(it.hasNext()) {
String key = it.next();
String value = prop.getProperty(key);
System.out.println(key+"=="+value);
}
}
方法的可变参数
方法的可变参数,是JDK1.5出现的特性
解决的问题 : 方法中参数的类型确定,参数个数不确定
格式 :
修饰符 返回值类型 方法名(int...a){
return ;
}
可变参数本质上是数组
public static void main(String[] args) {
//调用带有可变参数的方法
int sum = getSum(1,2,3,4,5,6,7,8,9);
System.out.println(sum);
}
/*
* 方法的可变参数
* 实现任意个整数的求和
*/
public static int getSum(int...a) {
int sum = 0;
//取出数组元素,求和 传统for,还是增强for
for(int i : a) {
sum = sum + i;
}
return sum;
}
注意事项 :
- 方法中,只能有1个可变参数
- 方法中,如果多个参数,可变参数只能写在最后一位
Map集合的练习
练习一 : 统计字符串中,每个字符出现的次数
需求 : 已知字符串 asba12as
结果输出 : a出现2次,b出现3次,c出现4次. A出现2次, 1出现1次,2出现1次
public static void main(String[] args) {
//1: 创建字符串
String str = "abcaba12AwAw13Wffw";
//2: 字符串转成char数组
char[] chs = str.toCharArray();
//3: 定义Map集合,键是字符,值出现的次数
Map<Character, Integer> map = new HashMap<Character, Integer>();
//4: 数组遍历,取出每个元素
for(char c : chs) {
//5: 数组的元素字符,到集合中找对应的值
Integer value = map.get(c);
//A: 找不到 = null
if(value == null) {
//字符做为键,1做为值,存储回集合
map.put(c, 1);
}else {
//找到了!= null
//值 ++
value++;
//字符做为键, 找到值++, 做为值,存储回集合
map.put(c, value);
}
}
//6: 遍历Map集合,看结果
// a出现2次,b出现3次,c出现4次. A出现2次, 1出现1次,2出现1次
for(Character key : map.keySet()) {
Integer value = map.get(key);
System.out.println("字符"+key+"出现了"+value+"次");
}
}
练习二 : 集合嵌套
-
List嵌套List
public static void main(String[] args) { //建立集合,存储字符串 List<String> smallList = new ArrayList<String>(); smallList.add("how"); smallList.add("are"); smallList.add("you"); List<String> smallList2 = new ArrayList<String>(); smallList2.add("i"); smallList2.add("love"); smallList2.add("java"); //建立集合,存储,小集合 List< List<String> > bigList = new ArrayList<List<String>>(); //小集合,存储大集合 bigList.add(smallList); bigList.add(smallList2); iterator(bigList); } /* * 方法,遍历集合,遍历是大集合 */ public static void iterator( List< List<String> > bigList ) { //迭代器,遍历大集合 Iterator< List<String> > bigIt = bigList.iterator(); while(bigIt.hasNext()) { //取出大集合中的元素 List<String> smallList = bigIt.next(); //大集合的元素,是小集合 //迭代器遍历小集合 Iterator<String> smallIt = smallList.iterator(); while(smallIt.hasNext()) { //取出小集合的元素,字符串 String str = smallIt.next(); System.out.println(str); } } }
-
List嵌套Map
public static void main(String[] args) { //创建Map集合,键值字符串 Map<String, String> bigMap1 = new HashMap<String, String>(); bigMap1.put("a1", "1"); bigMap1.put("a2", "2"); bigMap1.put("a3", "3"); Map<String, String> bigMap2 = new HashMap<String, String>(); bigMap2.put("b1", "1"); bigMap2.put("b2", "2"); bigMap2.put("b3", "3"); //创建List集合,存储Map集合 List< Map<String, String> > bigList = new ArrayList<Map<String,String>>(); //两个小map集合,存储到List集合 bigList.add(bigMap1); bigList.add(bigMap2); iterator(bigList); } /* * 方法遍历大的List集合 */ public static void iterator(List< Map<String, String> > bigList) { //迭代器遍历List集合 Iterator< Map<String, String> > bigIt = bigList.iterator(); while(bigIt.hasNext()) { //取出List集合的元素 Map<String, String> map = bigIt.next(); //集合元素是Map集合 //遍历Map集合, keySet方法 Set<String> set = map.keySet(); //迭代器遍历Set集合 Iterator<String> setIt = set.iterator(); while(setIt.hasNext()) { //取出Set集合元素,是Map集合键 String key = setIt.next(); //取出Map集合的值 String value = map.get(key); System.out.println(key+"=="+value); } } }
-
Map嵌套Map
public static void main(String[] args) {
//阶段集合,包含学号,姓名
Map<String, String> firstMap = new HashMap<String, String>();
//第一阶段,集合,存储字符串
firstMap.put("001", "张三");
firstMap.put("002", "李四");
Map<String, String> secondMap = new HashMap<String, String>();
//第二阶段集合,存储字符串
secondMap.put("003", "王五");
secondMap.put("004", "赵六");
//创建学科集合, 键是阶段名,值是阶段 集合
Map<String, Map<String, String>> javaMap = new HashMap<String, Map<String,String>>();
javaMap.put("第一", firstMap);
javaMap.put("第二", secondMap);
//keySet(javaMap);
entrySet(javaMap);
}
/*
* 方法遍历javaMap集合,entrySet()方式
*/
public static void entrySet(Map<String, Map<String, String>> javaMap) {
//学科集合javaMap,方法entrySet(),获取学科集合的键值对,映射关系对象Entry
Set<Map.Entry<String, Map<String, String>>> javaMapEntrySet = javaMap.entrySet();
//迭代器,遍历Set集合
Iterator<Map.Entry<String, Map<String, String>>> javaMapEntryIt = javaMapEntrySet.iterator();
while(javaMapEntryIt.hasNext()) {
//取出Set集合元素,元素是javaMap学科集合的键值对关系对象
Map.Entry<String, Map<String, String>> javaMapEntry = javaMapEntryIt.next();
//获取javaMap阶段集合的键,是阶段名
String javaMapKey = javaMapEntry.getKey();
//获取javaMap集合值,是阶段的集合 (姓名,学号)
Map<String, String> jieDuanMap = javaMapEntry.getValue();
//遍历阶段jieDuanMap,方法entrySet()取出集合的键值对映射关系对象
Set<Map.Entry<String, String>> jieDaunEntrySet = jieDuanMap.entrySet();
//迭代器,遍历Set集合
Iterator<Map.Entry<String, String>> jieDuanEntryIt = jieDaunEntrySet.iterator();
while(jieDuanEntryIt.hasNext()) {
//取出Set集合的键,是阶段集合的键值对映射关系对象
Map.Entry<String, String> jieDuanMapEntry = jieDuanEntryIt.next();
//阶段集合的键,学号
String key = jieDuanMapEntry.getKey();
//阶段集合的值,姓名
String value = jieDuanMapEntry.getValue();
System.out.println(javaMapKey+"=="+key+"=="+value);
}
}
}
/*
* 方法遍历javaMap集合,keySet()方式
*/
public static void keySet(Map<String, Map<String, String>> javaMap) {
//学科Map集合,遍历,方法keySet(),存储键的Set集合
Set<String> javaSet = javaMap.keySet();
//迭代器遍历Set集合
Iterator<String> javaIt = javaSet.iterator();
while(javaIt.hasNext()) {
//取出Set集合元素,是javaMap集合的键,阶段名字
String javaMapKey = javaIt.next();
//取出javaMap学科集合的值,值是个阶段的Map集合
Map<String, String> jieDuanMap = javaMap.get(javaMapKey);
//遍历阶段的Map集合, 调用方法keySet()拿出阶段Map集合的键
Set<String> jieDuanSet = jieDuanMap.keySet();
//迭代器遍历Set集合
Iterator<String> jieDuanIt = jieDuanSet.iterator();
while(jieDuanIt.hasNext()) {
//取出Set集合的元素,是阶段Map集合的键,学号
String key = jieDuanIt.next();
//取出阶段集合的值,姓名
String value = jieDuanMap.get(key);
System.out.println(javaMapKey+"=="+key+"=="+value);
}
}
}
练习三 : 斗地主排序
原理 : 需要自定义顺序
顺序 : 333344445555…AAAA2222王王
自定义顺序的思想 : 编号思想 0123…53 (数字的自然顺序)
每一个牌(字符串)和编号进行对应, 键值对思想实现. 编号为键,牌为值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yRfXVruf-1595508828115)(images/斗地主的排序思想.jpg)]