29.Map,可变参数
1.Map集合
1.1Map集合概述和特点【理解】
单列集合一次存一个元素
双列集合一次存两个元素
键:不能重复的 值:可以重复的
-
Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
-
键和值是一一对应的,每一个键只能找到自己对应的值
-
键不可以重复,值可以重复
- (键+值)这个整体 我们称之为“键值对”或者“键值对对象”,在Java中交做“Entry对象”。
- 举例:学生的学号和姓名
- itheima001 小智
- itheima002 小美
- itheima003 小胖
- 创建Map集合的对象
- 多态的方式
- 具体的实现类HashMap
-
Map集合的基本使用
package com.itheima.mapdemo1; import java.util.HashMap; import java.util.Map; /* * Map的基本使用 * */ public class MyMap1 { public static void main(String[] args) { Map<String,String> map=new HashMap<>(); map.put("itheima001","小智"); map.put("itheima002","小美"); map.put("itheima003","小胖"); System.out.println(map); } }
1.2Map集合的基本功能【应用】
-
方法介绍
方法名 说明 V put(K key,V value) 添加元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean containsKey(Object key) 判断集合是否包含指定的键 boolean containsValue(Object value) 判断集合是否包含指定的值 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中键值对的个数 -
示例代码
package com.itheima.mapdemo1; import java.util.HashMap; import java.util.Map; public class MyMap2 { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("itheima001", "小智"); map.put("itheima002", "小美"); map.put("itheima003", "小胖"); map.put("itheima004", "小黑"); map.put("itheima005", "大师"); //method1(map); //method2(map); //method3(map); //method4(map); //method5(map); //method6(map); //method7(map); } public static void method7(Map<String, String> map) { //int size() 集合的长度,也就是集合中键值对的个数 int size = map.size(); System.out.println(size); } public static void method6(Map<String, String> map) { //boolean isEmpty() 判断集合是否为空 boolean empty = map.isEmpty(); System.out.println(empty);//false map.clear(); boolean empty2 = map.isEmpty(); System.out.println(empty2);//true } public static void method5(Map<String, String> map) { //boolean containsValue(Object value) 判断集合是否包含指定的值 boolean result1 = map.containsValue("小智"); boolean result2 = map.containsValue("aaa"); System.out.println(result1);//true System.out.println(result2);//false } public static void method4(Map<String, String> map) { //boolean containsKey(Object key) 判断集合是否包含指定的键 boolean result1 = map.containsKey("itheima001"); boolean result2 = map.containsKey("itheima006"); System.out.println(result1);//true System.out.println(result2);//false } public static void method3(Map<String, String> map) { //void clear() 移除所有的键值对元素 map.clear(); System.out.println(map); } public static void method2(Map<String, String> map) { //V remove(Object key) 根据键删除键值对元素 String s = map.remove("itheima001"); System.out.println(s); System.out.println(map); } public static void method1(Map<String, String> map) { //V put(K key,V value) 添加元素 //如果要添加的键不存在,那么会把键值对都添加到集合中 //如果要添加的键是存在的,那么会覆盖原先的值,把原先的值当作返回值进行返回 String s = map.put("itheima001", "aaa"); System.out.println(s); System.out.println(map); } }
1.4Map集合的遍历(方式1)【应用】
-
遍历思路
-
我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
-
遍历丈夫的集合,获取到每一个丈夫
-
根据丈夫去找对应的妻子
-
-
-
步骤分析
-
- 创建一个集合添加元素,创建对象put
- 获取所有键的集合。用keySet()方法实现
-
遍历键的集合,获取到每一个键。用增强for实现
-
根据键去找值。用get(Object key)方法实现
- 打印得到的键和值,输出语句
-
代码实现
package com.itheima.mapdemo1; import java.util.HashMap; import java.util.Set; public class MyMap3 { public static void main(String[] args) { HashMap<String,String> map=new HashMap<>(); map.put("1号丈夫","一号妻子"); map.put("2号丈夫","二号妻子"); map.put("3号丈夫","三号妻子"); map.put("4号丈夫","四号妻子"); map.put("5号丈夫","五号妻子"); //获取所有的键 Set<String> keys = map.keySet(); //遍历Set集合得到每一个键 for (String key : keys) { //通过每一个键,来获取对应的值 String value = map.get(key); System.out.println(key+"======"+value); } } }
1.5Map集合的遍历(方式2)【应用】
-
遍历思路
-
我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
获取所有结婚证的集合
-
遍历结婚证的集合,得到每一个结婚证
-
根据结婚证获取丈夫和妻子
-
-
-
步骤分析
-
获取所有键值对对象的集合
-
Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
-
-
遍历键值对对象的集合,得到每一个键值对对象
-
用增强for实现,得到每一个Map.Entry
-
-
根据键值对对象获取键和值
-
用getKey()得到键
-
用getValue()得到值
- 业务逻辑,打印键和值 -------输出语句
-
-
代码实现
package com.itheima.mapdemo1; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MyMap4 { public static void main(String[] args) { HashMap<String,String> map=new HashMap<>(); map.put("1号丈夫","一号妻子"); map.put("2号丈夫","二号妻子"); map.put("3号丈夫","三号妻子"); map.put("4号丈夫","四号妻子"); map.put("5号丈夫","五号妻子"); //首先要获取到所有的键值对对象 //set集合中装的是键值对对象(Entry对象) //而Entry里面装的是键和值 Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { //得到每一个键值对对象 String key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"==="+value); } } }
2.HashMap集合
2.1HashMap集合概述和特点【理解】
HashMap是Map里面的一个实现类
没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
-
HashMap底层是哈希表结构的
-
依赖hashCode方法和equals方法保证键的唯一
-
如果键要存储的是自定义对象,需要重写hashCode和equals方法
2.2HashMap集合应用案例【应用】
-
案例需求
-
创建一个HashMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
-
要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
- 思路:
- 1.定义学生类
- 2.创建HashMap集合对象
- 3.创建学生对象
- 4.把学生添加到集合
- 5.遍历集合
-
-
学生类
package com.itheima.mapdemo1; public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
实现类
package com.itheima.mapdemo1; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Map的练习 * */ public class MyMap5 { public static void main(String[] args) { HashMap<Student, String> hm = new HashMap<>(); Student s1 = new Student("xiaohei", 23); Student s2 = new Student("dapang", 22); Student s3 = new Student("xiaomei", 22); hm.put(s1, "江苏"); hm.put(s2, "北京"); hm.put(s3, "天津"); //第一种,先获取到每一个键,再通过每一个键来找对应的值 Set<Student> keys = hm.keySet(); for (Student key : keys) { String value = hm.get(key); System.out.println(key + "===" + value); } System.out.println("=========================="); //先获取到许哦有的键值对对象,在获取到里面的每一个键和每一个值 Set<Map.Entry<Student, String>> entries = hm.entrySet(); for (Map.Entry<Student, String> entry : entries) { Student key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"==="+value); } System.out.println("========================="); //第三种方式 hm.forEach( (Student key,String value)->{ System.out.println(key+"==="+value); } ); } }
3.TreeMap集合
3.1TreeMap集合概述和特点【理解】
TreeMap是Map里面的一个实现类
没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
-
TreeMap底层是红黑树结构
-
依赖自然排序或者比较器排序,对键进行排序
-
如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则
3.2TreeMap集合应用案例一【应用】
-
案例需求
-
创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历
-
要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序
- 思路:
- 1.定义学生类
- 2.创建TreeMap集合
- 3.创建学生对象
- 4.把学生添加到集合
- 5.遍历集合
-
-
代码实现
学生类
package com.itheima.maptest; public class Student /*implements Comparable<Student>*/ { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } // @Override // public int compareTo(Student o) { // //按照年龄进行排序 // int result=this.getAge()-o.getAge(); // // //次要条件,按照姓名排序 // result=result==0?this.getName().compareTo(o.getName()):result; // return result; // } }
实现类
package com.itheima.maptest; import java.util.Comparator; import java.util.TreeMap; /** * *需求:创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历 * 要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序 * */ public class Test1 { public static void main(String[] args) { TreeMap<Student,String> tm=new TreeMap<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int result = o1.getAge() - o2.getAge(); result=result==0?o1.getName().compareTo(o2.getName()):result; return result; } }); Student s1 = new Student("xiaohei", 23); Student s2 = new Student("dapang", 22); Student s3 = new Student("xiaomei", 22); tm.put(s1,"江苏"); tm.put(s2,"北京"); tm.put(s3,"天津"); tm.forEach( (Student key,String value)->{ System.out.println(key+"===="+value); } ); } }
3.3TreeMap集合应用案例二【应用】
-
案例需求
-
给定一个字符串,要求统计字符串中每个字符出现的次数。
-
举例: 给定字符串是“aababcabcdabcde”,在控制台输出: “a(5)b(4)c(3)d(2)e(1)”
- Map集合中,键存字符,值存出现的次数
- 到集合中看是否包含这个字符
- 如果不包含,表示是第一次出现
- 如果包含,表是不是第一次出现
-
-
代码实现
package com.itheima.maptest; import java.util.TreeMap; /* * * 给定字符串是“aababcabcdabcde”, * 在控制台输出: “a(5)b(4)c(3)d(2)e(1)” * * */ public class Test2 { public static void main(String[] args) { String s="aababcabcdabcde"; TreeMap<Character,Integer> tm=new TreeMap<>(); //遍历字符串,得到每一个字符 for (int i = 0; i < s.length(); i++) { //c依次表示字符串中的每一个字符 char c = s.charAt(i); if (!tm.containsKey(c)){ //表示当前字符是第一次出现 tm.put(c,1); }else{ //存在,表示当前字符已经出现过了 //先获取这个字符已经出现的次数 Integer count=tm.get(c); //自增。表示这个字符又出现了一次 count++; //将自增后的结果再次添加到集合中 tm.put(c,count); } } //a(5)b(4)c(3)d(2)e(1) //System.out.println(tm); tm.forEach( (Character key,Integer value)->{ System.out.print(key+"("+value+")"); } ); } }
4.可变参数
4.1可变参数【应用】
-
可变参数介绍
-
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
-
方法的参数类型已经确定,个数不确定,我们可以使用可变参数
-
-
可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名) { }
- 范例:public static int sum(int...a){ }
-
可变参数的注意事项
-
这里的变量其实是一个数组
-
如果一个方法有多个参数,包含可变参数,可变参数要放在最后
-
-
可变参数的基本使用
package com.itheima.variableparameter; /* * * 需求:定义一个方法求N个数的和 * 可变参数实现 * */ public class MyVariableParameter3 { public static void main(String[] args) { int sum1=getSum(1,2,3,4,5); System.out.println(sum1); } public static int getSum(int number,int...arr){ int sum=0; for (int i = 0; i < arr.length; i++) { sum+=arr[i]; } return sum; } }
4.2创建不可变集合【理解】
-
方法介绍
- static <E> List<E> of(E…elements) 创建一个具有指定元素的List集合对象
static <E> Set<E> of(E…elements) 创建一个具有指定元素的Set集合对象
static <K , V> Map<K,V> of(E…elements) 创建一个具有指定元素的Map集合对象 -
-
在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合
-
这个集合不能添加,不能删除,不能修改
-
-
-
在Map接口中,还有一个ofEntries方法可以提高代码的阅读性
-
首先会把键值对封装成一个Entry对象,再把这个Entry对象添加到集合当中
-
-
示例代码
package com.itheima.variableparameter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; public class MyVariableParameter4 { public static void main(String[] args) { //static <E> Set<E> of(E…elements) 创建一个具有指定元素的Set集合对象 //static <K , V> Map<K,V> of(E…elements) 创建一个具有指定元素的Map集合对象 //method1(); //method2(); //method3(); method4(); } public static void method4() { Map<String, String> map = Map.ofEntries( Map.entry("张三", "江苏"), Map.entry("李四", "北京")); System.out.println(map); } public static void method3() { Map<String, String> map = Map.of("张三", "江苏", "李四", "北京", "王五", "天津"); System.out.println(map); } public static void method2() { //传递的参数之中不能有重复的元素 Set<String> set = Set.of("a", "b", "c", "d", "a"); System.out.println(set); } public static void method1() { // static <E> List<E> of(E…elements) 创建一个具有指定元素的List集合对象 List<String> list = List.of("a", "b", "c", "d"); System.out.println(list); //list.add("q"); //list.remove("a"); //list.set(0,"A"); //集合的批量添加 //首先是通过调用List.of方法来创建一个不可变的集合,of方法的形参就是一个可变参数。 //再创建一个ArrayList集合,并把这个不可变的集合中所有的数据都添加到ArrayList中 ArrayList<String> list1 = new ArrayList<>(List.of("a", "b", "c", "d")); System.out.println(list1); } }