集合进阶2
双列集合
Map的常见API
Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的
import java.util.HashMap;
import java.util.Map;public class MaoDemo1 {public static void main(String[] args) {/*V put(K key,V value)添加元素V remove(Object key)根据键删除键值对元素void clear()移除所有的键值对元素boolean containskey(Object key)判断集合是否包含指定的键boolean containsValue(Object value) 判断集合是否包含指定的值booleanisEmpty()判断集合是否为空intsize()集合的长度,也就是集合中键值对的个数*///1.创建Map集合的对象Map<String, String> map = new HashMap<>();//2.添加元素//put方法的细节://添加/覆盖//在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中//在添加数据的时候,如果键是存在的,那么会把原有的键值观对对象覆盖,会把被覆盖的值进行返回。map.put("aaa", "bbb");map.put("bbb", "ccc");map.put("ccc", "ddd");//判断是否包含boolean keyRelsult = map.containsKey("aaa");System.out.println(keyRelsult);boolean valueRelsult = map.containsValue("fff");System.out.println(valueRelsult);//清空//map.clear();boolean result = map.isEmpty();System.out.println(result);//键值对长度int a = map.size();System.out.println(a);//3.集合打印System.out.println(map);}
}运行:
true
false
false
3
{aaa=bbb, ccc=ddd, bbb=ccc}
Map遍历方式
- set<对象> keys = map.keySet()
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class MapDemo2 {public static void main(String[] args) {//1.创建集合Map<String, String> map = new HashMap<>();//2.添加元素map.put("aaa", "bbb");map.put("abc", "cba");map.put("ddd", "fff");//3.通过键找值//3.1获取所有的键,把这些键放到一个单列集合当中Set<String> keys = map.keySet();//3,2遍历单列集合,得到每一个键for (String key : keys) {//3.3利用map集合中的键获取对应的值String value = map.get(key);System.out.println(key + "=" + value);}}
}运行:
aaa=bbb
abc=cba
ddd=fff
entry
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class MapDemo3 {public static void main(String[] args) {//1.创建集合Map<String,String> map = new HashMap<String,String>();//2.添加元素map.put("aaa", "bbb");map.put("ccc", "ddd");map.put("eee", "fff");//3.Map集合的第二种遍历方式//通过键值对对象进行遍历//3.1通过一个方法获取所有键值对对象,返回一个set集合Set<Map.Entry<String,String>> entries = map.entrySet();//3.2遍历entries这个集合,去得到里面每一个键值对对象for (Map.Entry<String,String> entry : entries) {//entry ---> "aaa","bbb"//3.3利用entry调用get方法获取键值对String key = entry.getKey();String value = entry.getValue();System.out.println(key + "=" + value);}}
}运行:
aaa=bbb
ccc=ddd
eee=fff
第三种遍历方式
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;public class MapDemo4 {public static void main(String[] args) {//1.创建集合Map<String, String> map = new HashMap<String, String>();//2.添加元素map.put("鲁迅", "这句话是我说的");map.put("曹操", "不可能绝对不可能");map.put("刘备", "接着奏乐接着舞");map.put("柯镇恶", "看我眼色行事");//3,利用lambda表达式进行遍历map.forEach((s, s2) -> System.out.println(s + ":" + s2));}
} 运行:
刘备:接着奏乐接着舞
柯镇恶:看我眼色行事
鲁迅:这句话是我说的
曹操:不可能绝对不可能
HashMap
- HashMap底层是哈希表结构的
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键存储的是自定义对象,需要重写hashCode和equal方法
- 如果值存储自定义对象,不需要重写hashCode和equals方法
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;public class MapDemo5 {public static void main(String[] args) {/*需求:创建一个HashMap集合,键是学生对象(Student),值是籍贯(String)。存储三个键值对元素,并遍历要求:同姓名,同年龄认为是同一个学生*///1.创建集合HashMap<Student, String> hm = new HashMap<Student, String>();//2.创建学生对象Student s1 = new Student("zhnagsan", 23);Student s2 = new Student("lisi", 25);Student s3 = new Student("wangwu", 24);//3.添加元素hm.put(s1, "江苏");hm.put(s2, "浙江");hm.put(s3, "福建");//4.遍历集合Set<Student> set = hm.keySet();for (Student s : set) {String value = hm.get(s);System.out.println(s + "=" + 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, s) -> System.out.println(student + "=" + s));}
}运行:
Student{name='wangwu', age=24}=福建
Student{name='lisi', age=25}=浙江
Student{name='zhnagsan', age=23}=江苏
-----------------------------
Student{name='wangwu', age=24}=福建
Student{name='lisi', age=25}=浙江
Student{name='zhnagsan', age=23}=江苏
---------------------------
Student{name='wangwu', age=24}=福建
Student{name='lisi', age=25}=浙江
Student{name='zhnagsan', age=23}=江苏
练习
import java.util.*;public class MapDemo6 {public static void main(String[] args) {/*某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。*///1.需要同学先投票//定义一个数组,储存4个景点String[] arr = {"A", "b", "C", "D"};//利用随机数模拟80个同学的投票,并把投票结果储存起来ArrayList<String> list = new ArrayList<>();Random r = new Random();for (int i = 0; i < 80; i++) {int index = r.nextInt(arr.length);list.add(arr[index]);}//2.如果添加的东西比较多,不方便使用计数器思想//定义Map集合HashMap<String, Integer> map = new HashMap<>();for (String s : list) {//判断当前景点在map中是否存在if (map.containsKey(s)) {//存在//先获取当前景点的投票次数int count = map.get(s);//表示当前景点又被投了一次count++;//再把新的次数再次添加到集合当中map.put(s, count);//覆盖原先的} else {//不存在map.put(s, 1);}}System.out.println(map);//求最大值int max = 0;Set<Map.Entry<String, Integer>> entries = map.entrySet();for (Map.Entry<String, Integer> entry : entries) {int count = entry.getValue();if (count > max) {max = count;}}System.out.println(max);//4.判断哪个景点跟最大值一样,如果一样,打印出来for (Map.Entry<String, Integer> entry : entries) {int count = entry.getValue();if (count == max) {System.out.println(entry.getKey());}}}
}运行:
{A=21, b=20, C=24, D=15}
24
C
LinkedHashMap
- 由键决定:有序、不重复、无索引。
- 这里的有序指的是保证存储和取出的元素顺序一致
- 原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。(两个元素互相记录地址值)
- 有序的实现
练习:
import java.util.LinkedHashMap;public class LinkedHashMapdemo {public static void main(String[] args) {//1.创建集合LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();//2.添加集合map.put(1, "one");map.put(2, "two");map.put(3, "three");map.put(4, "four");map.put(3, "five");//3.打印集合System.out.println(map);}
}运行:
{1=one, 2=two, 3=five, 4=four}
TreeMap
- 按照键的升序进行排列
可变参数
public class ArgDemo {public static void main(String[] args) {//可变参数的小细节://1.在方法的形参中最多只能写一个可变参数//可变参数,理解为一个大胖子,有多少吃多少//2.在方法的形参当中,如果出了可变参数以外,还有其他的形参那么可变参数要写在最后getSum(1,2, 3, 4, 5, 6, 7, 8, 9, 10);}public static int getSum(int a, int... args) {return 0;}
}
Collections
Collections常用API
package com.itheima.a07mycollections;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;public class CollectionsDemo2 {public static void main(String[] args) {/*public static <T> void sort(List<T> list) 排序public static <T> void sort(List<T> list, Comparator<T> c) 根据指定的规则进行排序public static <T> int binarySearch (List<T> list, T key) 以二分查找法查找元素public static <T> void copy(List<T> dest, List<T> src) 拷贝集合中的元素public static <T> int fill (List<T> list, T obj) 使用指定的元素填充集合public static <T> void max/min(Collection<T> coll) 根据默认的自然排序获取最大/小值public static <T> void swap(List<?> list, int i, int j) 交换集合中指定位置的元素*/System.out.println("-------------sort默认规则--------------------------");//默认规则,需要重写Comparable接口compareTo方法。Integer已经实现,按照从小打大的顺序排列//如果是自定义对象,需要自己指定规则ArrayList<Integer> list1 = new ArrayList<>();Collections.addAll(list1, 10, 1, 2, 4, 8, 5, 9, 6, 7, 3);Collections.sort(list1);System.out.println(list1);System.out.println("-------------sort自己指定规则规则--------------------------");Collections.sort(list1, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});System.out.println(list1);Collections.sort(list1, (o1, o2) -> o2 - o1);System.out.println(list1);System.out.println("-------------binarySearch--------------------------");//需要元素有序ArrayList<Integer> list2 = new ArrayList<>();Collections.addAll(list2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);System.out.println(Collections.binarySearch(list2, 9));System.out.println(Collections.binarySearch(list2, 1));System.out.println(Collections.binarySearch(list2, 20));System.out.println("-------------copy--------------------------");//把list3中的元素拷贝到list4中//会覆盖原来的元素//注意点:如果list3的长度 > list4的长度,方法会报错ArrayList<Integer> list3 = new ArrayList<>();ArrayList<Integer> list4 = new ArrayList<>();Collections.addAll(list3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);Collections.addAll(list4, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);Collections.copy(list4, list3);System.out.println(list3);System.out.println(list4);System.out.println("-------------fill--------------------------");//把集合中现有的所有数据,都修改为指定数据ArrayList<Integer> list5 = new ArrayList<>();Collections.addAll(list5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);Collections.fill(list5, 100);System.out.println(list5);System.out.println("-------------max/min--------------------------");//求最大值或者最小值ArrayList<Integer> list6 = new ArrayList<>();Collections.addAll(list6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);System.out.println(Collections.max(list6));System.out.println(Collections.min(list6));System.out.println("-------------max/min指定规则--------------------------");// String中默认是按照字母的abcdefg顺序进行排列的// 现在我要求最长的字符串// 默认的规则无法满足,可以自己指定规则// 求指定规则的最大值或者最小值ArrayList<String> list7 = new ArrayList<>();Collections.addAll(list7, "a","aa","aaa","aaaa");System.out.println(Collections.max(list7, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o1.length() - o2.length();}}));System.out.println("-------------swap--------------------------");ArrayList<Integer> list8 = new ArrayList<>();Collections.addAll(list8, 1, 2, 3);Collections.swap(list8,0,2);System.out.println(list8);}
}
练习
Test1
import java.util.ArrayList;
import java.util.Collections;public class Test1 {public static void main(String[] args) {//随机点名其//1.定义集合ArrayList<String> list = new ArrayList<>();//2.添加元素Collections.addAll(list,"小明","小红","小李","小芳");//3.随机点名//打乱Collections.shuffle(list);String name = list.get(0);System.out.println(name);}
}
Test2
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;public class Test2 {public static void main(String[] args) {/*班级里有N个学生要求:70%的概率随机到男生30%的概率随机到女生"范闲","范建",范统","杜子腾","宋合泛","侯笼藤","朱益群","朱穆朗玛峰","杜琦燕","袁明媛","李猜","田蜜蜜",*///1111111000 70%+30%//1.创建集合ArrayList<Integer> list = new ArrayList<Integer>();//2.添加元素Collections.addAll(list, 1,1,1,1,1,1,1);Collections.addAll(list,0,0,0);//3.打乱集合中的数据Collections.shuffle(list);//4.从集合中随机抽取0或1Random random = new Random();int index = random.nextInt(list.size());Integer number = list.get(index);System.out.println(number);//5.定义两个集合来储存男女生姓名ArrayList<String> boyList = new ArrayList<>();ArrayList<String> girlList = new ArrayList<>();Collections.addAll(boyList,"范闲","范建","范统","杜子腾","宋合泛","侯笼藤","朱益群","朱穆朗玛峰");Collections.addAll(girlList,"杜琦燕","袁明媛","李猜","田蜜蜜");//6.判断此时是从boyList里面还是girlList里面抽取if(number == 1){int boyIndex = random.nextInt(boyList.size());String name = boyList.get(boyIndex);System.out.println(name);}else{int girlIndex = random.nextInt(girlList.size());String name = girlList.get(girlIndex);System.out.println(name);}}
}