文章目录
- 一、双列集合Map
- 1.1 双列集合介绍
- 1.2 双列集合Map常见API
- 1.3 Map集合遍历方式
- 1.3.1 通过集合的全部键来遍历集合
- 1.3.2 Map集合遍历方式2
- 1.3.3 Map集合遍历方式3
- 二、Map集合的实现类
- 2.1 HashMap类
- 2.2 LinkedHashMap
- 2.3 TreeMap
- 三、可变参数
- 四、Collections类
- 五、集合的嵌套
一、双列集合Map
1.1 双列集合介绍
所谓双列集合,就是说集合中的元素是一对一对的。Map集合中的每一个元素是以
key=value
的形式存在的,一个key=value
就称之为一个键值对,而且在Java中有一个类叫Entry类,Entry的对象用来表示键值对对象。
- 键不能重复,值可以重复,每一个键只能找到自己对应的值。
1.2 双列集合Map常见API
public class MapTest2 {public static void main(String[] args) {// 1.添加元素: 无序,不重复,无索引。//Map是一个接口,无法创建对象,只能创建其实现类的对象HashMapMap<String, Integer> map = new HashMap<>();map.put("手表", 100);map.put("手表", 220);map.put("手机", 2);map.put("Java", 2);map.put(null, null);System.out.println(map);// map = {null=null, 手表=220, Java=2, 手机=2}// 2.public int size():获取集合的大小System.out.println(map.size());// 3、public void clear():清空集合//map.clear();//System.out.println(map);// 4.public boolean isEmpty(): 判断集合是否为空,为空返回true ,反之!System.out.println(map.isEmpty());// 5.public V get(Object key):根据键获取对应值int v1 = map.get("手表");System.out.println(v1);System.out.println(map.get("手机")); // 2System.out.println(map.get("张三")); // null// 6. public V remove(Object key):根据键删除整个元素(删除键会返回键的值)System.out.println(map.remove("手表"));System.out.println(map);// 7.public boolean containsKey(Object key): 判断是否包含某个键 ,包含返回true ,反之System.out.println(map.containsKey("手表")); // falseSystem.out.println(map.containsKey("手机")); // trueSystem.out.println(map.containsKey("java")); // falseSystem.out.println(map.containsKey("Java")); // true// 8.public boolean containsValue(Object value): 判断是否包含某个值。System.out.println(map.containsValue(2)); // trueSystem.out.println(map.containsValue("2")); // false// 9.public Set<K> keySet(): 获取Map集合的全部键。Set<String> keys = map.keySet();System.out.println(keys);// 10.public Collection<V> values(); 获取Map集合的全部值。Collection<Integer> values = map.values();System.out.println(values);// 11.把其他Map集合的数据倒入到自己集合中来。(拓展)Map<String, Integer> map1 = new HashMap<>();map1.put("java1", 10);map1.put("java2", 20);Map<String, Integer> map2 = new HashMap<>();map2.put("java3", 10);map2.put("java2", 222);map1.putAll(map2); // putAll:把map2集合中的元素全部倒入一份到map1集合中去。System.out.println(map1);System.out.println(map2);}
}
1.3 Map集合遍历方式
1.3.1 通过集合的全部键来遍历集合
通过键找值的方法遍历集合,由于键值的唯一性
public class MapTest1 {public static void main(String[] args) {// 准备一个Map集合。Map<String, Double> map = new HashMap<>();map.put("蜘蛛精", 162.5);map.put("蜘蛛精", 169.8);map.put("紫霞", 165.8);map.put("至尊宝", 169.5);map.put("牛魔王", 183.6);System.out.println(map);// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}// 1、获取Map集合的全部键Set<String> keys = map.keySet();// System.out.println(keys);// [蜘蛛精, 牛魔王, 至尊宝, 紫霞]// key// 2、增强for遍历全部的键,根据键获取其对应的值for (String key : keys) {// 根据键获取对应的值double value = map.get(key);System.out.println(key + "=====>" + value);}}
}
1.3.2 Map集合遍历方式2
通过键值对的方法遍历集合
直接获取每一个Entry对象,把Entry存储到 Set集合中去,再通过Entry对象获取键和值。
public class MapTest2 {public static void main(String[] args) {Map<String, Double> map = new HashMap<>();map.put("蜘蛛精", 169.8);map.put("紫霞", 165.8);map.put("至尊宝", 169.5);map.put("牛魔王", 183.6);System.out.println(map);// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}// entries = [(蜘蛛精=169.8), (牛魔王=183.6), (至尊宝=169.5), (紫霞=165.8)]// entry = (蜘蛛精=169.8)// entry = (牛魔王=183.6)// ...// 1、调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合//entry是Map类中的内部接口Set<Map.Entry<String, Double>> entries = map.entrySet();for (Map.Entry<String, Double> entry : entries) {String key = entry.getKey();double value = entry.getValue();System.out.println(key + "---->" + value);}}
}
1.3.3 Map集合遍历方式3
用forEach方法
/*** 目标:掌握Map集合的第二种遍历方式:键值对。*/
public class MapTest3 {public static void main(String[] args) {Map<String, Double> map = new HashMap<>();map.put("蜘蛛精", 169.8);map.put("紫霞", 165.8);map.put("至尊宝", 169.5);map.put("牛魔王", 183.6);System.out.println(map);// map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}//遍历map集合,传递匿名内部类map.forEach(new BiConsumer<String, Double>() {@Overridepublic void accept(String k, Double v) {System.out.println(k + "---->" + v);}});//遍历map集合,传递Lambda表达式map.forEach(( k, v) -> {System.out.println(k + "---->" + v);});}
}
二、Map集合的实现类
2.1 HashMap类
HashMap底层原理和HashSet是一样的。我们往HashSet集合中添加元素时,实际上是把元素作为添加添加到了HashMap集合中。故两个类的常用方法都一样
下面是Map集合的体系结构,HashMap集合的特点是由键决定的: 它的键
是无序、不能重复,而且没有索引的。再各种Map集合中也是用得最多的一种集合。
Hash和HashMap在本质上是一样的,底层原理都依赖于哈希表来实现
2.2 LinkedHashMap
与单列结合的哈希表一样,底层是基于双链表实现的
public class Test2LinkedHashMap {public static void main(String[] args) {// Map<String, Integer> map = new HashMap<>(); // 按照键 无序,不重复,无索引。LinkedHashMap<String, Integer> map = new LinkedHashMap<>(); // 按照键 有序,不重复,无索引。map.put("手表", 100);map.put("手表", 220);map.put("手机", 2);map.put("Java", 2);map.put(null, null);System.out.println(map);}
}
运行结果:
可见:
- 键值相同时,值会被覆盖
- 存入与取出的次序一致
2.3 TreeMap
TreeMap集合的特点也是由键决定的,默认按照键的升序排列,键不重复,也是无索引的。
TreeMap集合的底层原理和TreeSet也是一样的,底层都是红黑树实现的。所以可以对键进行排序。
TreeMap类在排序是和TreeSet一样也有两种方法
排序方式1:写一个Student类,让Student类实现Comparable接口
//第一步:先让Student类,实现Comparable接口
public class Student implements Comparable<Student>{private String name;private int age;private double height;//无参数构造方法public Student(){}//全参数构造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()省略//按照年龄进行比较,只需要在方法中让this.age和o.age相减就可以。/*原理:在往TreeSet集合中添加元素时,add方法底层会调用compareTo方法,根据该方法的结果是正数、负数、还是零,决定元素放在后面、前面还是不存。*/@Overridepublic int compareTo(Student o) {//this:表示将要添加进去的Student对象//o: 表示集合中已有的Student对象return this.age-o.age;}
}
排序方式2:在创建TreeMap集合时,直接传递Comparator比较器对象。
public class Test3TreeMap {public static void main(String[] args) {Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight());}});
// Map<Student, String> map = new TreeMap<>(( o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()));map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");map.put(new Student("至尊宝", 23, 163.5), "水帘洞");map.put(new Student("牛魔王", 28, 183.5), "牛头山");System.out.println(map);}
}
三、可变参数
当函数接收的数据数量不确定时,可以用到可变参数
public class Test {public static void main(String[] args) {System.out.println(getSum(1,2,3,4,5));}//普通参数放在可变参数之前,且方法中最多只接收一个可变参数public static int getSum(double agg,int... args){int sum=0;for (int i : args) {sum += i;}return sum;}
}
注意:
- 方法的形参最多接收一个可变参数
- 可变参数的本质时数组
- 普通参数应该放在可变参数之前
四、Collections类
该类是一个集合的工具类
public class CollectionsDemo {public static void main(String[] args) {//该类的两个常用方法ArrayList<String> arr=new ArrayList<>();//1.集合的批量添加Collections.addAll(arr,"1","2","3","4");System.out.println(arr);//2.集合的打乱Collections.shuffle(arr);}
}
五、集合的嵌套
当有如下的需求时,一个键对应着多个值:
而又因为一个省份有多个城市,同一个省份的多个城市可以再用一个List集合来存储。
所以Map集合的键是String类型,而指是List集合类型
HashMap<String, List> map = new HashMap<>();
/*** 江苏省 = "南京市","扬州市","苏州市“,"无锡市","常州市"* 湖北省 = "武汉市","孝感市","十堰市","宜昌市","鄂州市"* 河北省 = "石家庄市","唐山市", "邢台市", "保定市", "张家口市"*/
public class Test {public static void main(String[] args) {// 1、定义一个Map集合存储全部的省份信息,和其对应的城市信息。Map<String, List<String>> map = new HashMap<>();List<String> cities1 = new ArrayList<>();Collections.addAll(cities1, "南京市","扬州市","苏州市" ,"无锡市","常州市");map.put("江苏省", cities1);List<String> cities2 = new ArrayList<>();Collections.addAll(cities2, "武汉市","孝感市","十堰市","宜昌市","鄂州市");map.put("湖北省", cities2);List<String> cities3 = new ArrayList<>();Collections.addAll(cities3, "石家庄市","唐山市", "邢台市", "保定市", "张家口市");map.put("河北省", cities3);System.out.println(map);List<String> cities = map.get("湖北省");for (String city : cities) {System.out.println(city);}map.forEach((p, c) -> {System.out.println(p + "----->" + c);});}
}