【java 13天进阶Day06】Map集合,HashMapTreeMap,斗地主、图书管理系统,排序算法
Map集合
-
Collection是单值集合体系。
-
Map集合是另一个集合体系,是一种双列集合,每个元素包含两个值。
-
Map集合的每个元素的格式:key=value(键值对元素)。
-
Map集合也被称为“键值对集合”。
-
Map集合的完整格式:{key1=value1 , key2=value2 , key3=value3 , …}
-
Map集合有啥用?
- 1.Map集合存储的信息更加的具体丰富。
- Collection: [“小李”,“上海”,“女”,“演员”,23,“广州”]
- Map : {name=“小李” , jiaxiang=“上海” , sex=“女” , age = 23 , addr=广州}
- 2.Map集合很适合做购物车这样的系统。
- Map: {娃娃=30 , huawei=1 , iphonex=1}
- 1.Map集合存储的信息更加的具体丰富。
-
注意:集合和泛型都只能支持引用数据类型,集合完全可以称为是对象容器,存储都是对象。
-
Map集合的体系:
- Map<K , V>(接口,Map集合的祖宗类)
- TreeMap<K , V>
- LinkedHashMap<K, V>(实现类)
- HashMap<K , V>(实现类,经典的,用的最多)
- TreeMap<K , V>
- Map<K , V>(接口,Map集合的祖宗类)
-
Map集合的特点:
- Map集合的特点都是由键决定的。
- Map集合的键是无序,不重复的,无索引的。
- Map集合后面重复的键对应的元素会覆盖前面的整个元素!
- Map集合的值无要求。
- Map集合的键值对都可以为null。
- HashMap:元素按照键是无序,不重复,无索引,值不做要求。
- LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求。
-
Map集合的常用API(重点中的重点)
- - public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。
- - public void putAll(Map<? extends K, ? extends V> var1):合并其他Map集合。
- - public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
- - public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
- - public Set keySet(): 获取Map集合中所有的键,存储到Set集合中。键是无序不重复的。
- - public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
- - public boolean containKey(Object key):判断该集合中是否有此键。
- - public boolean containsValue(Object var1):判断该集合中是否有此值。
- - public Collection values():获取所有的值,Map集合的值是不做要求的,可能重复,所以值要用Collection集合接收
Collection<Integer> values = maps.values();
-
Map集合的遍历方式
-
“键找值**”**的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
-
键值对”的方式遍历:难度较大。
-
Set<Map.Entry<String, Integer>> entries = maps.entrySet(); for (Map.Entry<String, Integer> entry : entries) {String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + "=>" + value); }
-
-
JDK 1.8开始之后的新技术:Lambda表达式。
-
maps.forEach((k, v) -> {System.out.println(k + "==>" + v);});
-
-
Map集合的键和值都可以存储自定义类型。
Map<Orange, String> maps = new HashMap<>();
- 注:如果希望Map集合认为自定义类型的键对象重复了,必须重写对象的hashCode()和equals()方法。
-
LinkedHashMap
- HashMap集合是无序不重复的键值对集合。HashSet集合相当于是HashMap集合的键都不带值。
- LinkedHashMap是HashMap的子类。添加的元素按照键有序,不重复的。
- LinkedHashMap集合是有序不重复的键值对集合。LinkedHashSet集合相当于是LinkedHashMap集合的键都不带值。
- 底层原理完全一样,都是基于哈希表按照键存储数据的,增删改查都很好,只是HashMap或者LinkedHashMap的键都多一个附属值。
TreeMap
- TreeMap集合按照键是可排序不重复的键值对集合。(默认升序)
- TreeMap集合按照键排序的特点与TreeSet是完全一样的。
- 小结:
- TreeMap集合和TreeSet集合都是排序不重复集合
- TreeSet集合的底层是基于TreeMap,只是键没有附属值而已。
- 所以TreeMap集合指定大小规则有2种方式:
- a.直接为对象的类实现比较器规则接口Comparable,重写比较方法(拓展方式)
- b.直接为集合设置比较器Comparator对象,重写比较方法
- 拓展:浮点型的大小比较建议使用Java自己的API Double.compare(double d1,double d2)
冒泡排序
- 作用:可以用于对数组或者对集合的元素进行大小排序。
- int[] arr = new int[] {55, 22, 99, 88};
- 思想:每次从数组的第一个位置开始两两比较。把较大的元素与较小的元素进行层层交换。最终把当前最大的一个元素存入到数组当前的末尾。
- 冒泡排序的核心点:每次两两比较找出当前最大值冒出到当前最后面即可!!
- 冒泡排序的实现核心:
- 1.确定总共需要冒几轮: 数组的长度-1.
- 2.每轮两两比较几次。
- i(轮数) 次数 每轮次数的规律:数组长度-i-1 次
- 0 3
- 1 2
- 2 1
-
public static void main(String[] args) {int[] arr = new int[]{55, 22, 99, 88};// 1.定义一个循环控制总共需要冒泡几轮:数组的长度-1for (int i = 0; i < arr.length - 1; i++) {// i = 0 j = 0 1 2// i = 1 j = 0 1// i = 2 j = 0// 2.控制每轮比较几次。for (int j = 0; j < arr.length - i - 1; j++) {// 如果当前元素大于后一个元素if (arr[j] > arr[j + 1]) {// 交换位置。大的元素必须后移!// 定义一个临时变量存储后一个元素int temp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = temp;}}}System.out.println("数组:" + Arrays.toString(arr));}
选择排序
- 选择排序的思想:从当前位置开始找出后面的较小值与该位置交换。
- 数组:int[] arr = {5 , 1 , 3 , 2}
- 选择排序的实现思路:
- (1)控制选择几轮:数组的长度-1.
- (2)控制每轮从当前位置开始比较几次。
- i(轮数) 次数
- 0 3
- 1 2
- 2 1
-
public static void main(String[] args) {int[] arr = {5, 1, 3, 2};// 1.定义一个循环控制选择几轮for (int i = 0; i < arr.length - 1; i++) {// 2.定义一个循环控制每轮比较几次,一定是以当前位置与后面元素比较// i =0 j = 1 2 3// i =1 j = 2 3// i =2 j = 3// 遍历后面的元素for (int j = i + 1; j < arr.length; j++) {// 拿当前位置与j指定的元素进行大小比较,后面的较小就交换位置if (arr[j] < arr[i]) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}System.out.println("数组:" + Arrays.toString(arr));}
二分查找
- 正常查找:从第一个元素开始遍历,一个一个的往后找,综合查找比较耗时。
- 二分查找:
- 二分查找的前提:对数组是有要求的,数组必须已经排好序。
- 每次先与中间的元素进行比较,如果大于往右边找,如果小于往左边找,如果等于就返回该元素索引位置!
- 如果没有该元素,返回-1。综合性能比较好!!
-
public static int binarySerach(int[] arr, int number) {// 3.记录当前区间搜索的开始索引和结束索引。int start = 0;int end = arr.length - 1;// 4.定义一个循环,反复去循环元素。while (start <= end) {// 5.取中间索引位置int middleIndex = (start + end) / 2;// 6.判断当前元素与中间元素的大小if (number < arr[middleIndex]) {// 7.往左边继续寻找,结束索引应该-1end = middleIndex - 1;} else if (number > arr[middleIndex]) {start = middleIndex + 1;} else if (number == arr[middleIndex]) {return middleIndex;}}// 如果上述循环执行完毕还没有返回索引,说明根本不存在该元素值,直接返回-1return -1;}
ps:b站课程《黑马程序员Java13天进阶》根据官方笔记结合自身情况整理的笔记
视频链接