集合的介绍(3)

Map

  • Map是一个集合,一种依照键(key)存储元素的容器,键(key)很像下标,在List中下标是整数。在Map中键(key)可以是任意类型的对象。Map中不能有重复的键(Key),每个键(key)都有一个对应的值(value)
  • Map接口的常用子类有如下四个:HashMapHashTableTreeMapConcurrentHashMap等…下面就展示HashMap以及HashTable

HashMap例子展示

package chapter06;

import java.util.HashMap;

public class Collection_HashMap {
public static void main(String[] args) throws Exception {

// TODO 集合 - Map - 以键值对的形式存储数据(key,value)
// HashMap : Hash + Map
// 数据存储是无序且不重复的
HashMap map = new HashMap();

// 添加数据:put
// 修改数据,put方法也可以修改数据,返回值就是被修改的值
map.put("zhangsan", "1");
System.out.println(map.put("zhangsan", "4")); // 返回被修改的值:1,用4覆盖掉原来的1
map.put("lisi", "2");
map.put("wangwu", "3");

// TODO 查询数据
System.out.println(map.get("zhangsan")); // 4

// TODO 删除数据
map.remove("zhangsan");

System.out.println(map); // {lisi=2, wangwu=3};zhangsan键值对被删掉了
}
}

Map接口中有如下常用方法

image

package chapter06;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Collection_HashMap2 {
public static void main(String[] args) throws Exception {

// TODO 集合 - Map
HashMap<String, String> map = new HashMap();

// 添加数据
// 修改数据
map.put("a", "0");
Object oldVal = map.put("a", "1");
System.out.println(oldVal);
// // 添加数据
map.putIfAbsent("b", "2");
map.putIfAbsent("b", "3");

Object b = map.replace("c", "4");
System.out.println(b);

map.clear();
map.put("zhangsan", "1");
map.put("lisi", "2");
map.put("wangwu", "3");

// TODO 通过key获取map集合中所有的value
Set set = map.keySet(); // 将map中所有的key映射成一个set
for (Object k : set) {
// 循环遍历map中的key输出对应value值
System.out.println(map.get(k)); // 1,2,3
}
// 判断map中是否包含有 zhangsan 这个key
System.out.println(map.containsKey("zhangsan")); // 包含返回true
map.containsValue("1"); // 判断map中是否包含有1这个value

// 将map中所有的value映射成一个集合
Collection values = map.values();
System.out.println(values); // [2, 1, 3]
// 当然也是可以循环遍历的
// for (Object value : values) {
// System.out.println(value);
// }

// System.out.println(map);

// TODO 获取键值对对象
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
// 以下的两种输出是一样的
// System.out.println(entry);
System.out.println(entry.getKey() + "=" + entry.getValue());
/*
* 循环遍历输出: lisi=2,zhangsan=1,wangwu=3
* */
}

// remove移除map中的数据
// map.remove("zhangsan"); // 移除 zhangsan 这个key的数据
map.remove("zhangsan", "1"); // 移除 zhangsan=1 这个key的数据,如果没有则不操作

// 因为map是集合的一个接口类,因此他也是可以使用以下的这些方法的
// map.size()
// map.isEmpty()
// map.clear();
// map.clone()

System.out.println(map); // 移除了zhangsan=1后输出 {lisi=2, wangwu=3}
}
}

Hashtable例子展示

package chapter07;

import java.util.HashMap;
import java.util.Hashtable;

public class Java11_Collection_Map_2 {
public static void main(String[] args) throws Exception {

// TODO 集合 - Map
// Hashtable
Hashtable table = new Hashtable();
table.put(null, null);
HashMap map = new HashMap();
map.put(null, null);
// 基本上HashMap里面有的方法,Hashtable都能用,如下:
// table.put()
// table.get()
// table.remove()

// 具体差别
// TODO 1. 实现方式不一样的 : 继承父类不一样
// TODO 2. 底层结构的容量不同: HashMap(16), Hashtable(11)
// TODO 3. HashMap的K,V都可以为null, Hashtable的K, V不能是null
// TODO 4. HashMap的数据定位采用的是Hash算法,但是Hashtable采用的就是hashcode
// TODO 5. HashMap的性能较高,但是Hashtable较低

}
}

迭代器

  • 迭代器(iterator)是一个非常重要的概念在集合中,它可以帮助我们于遍历集合(Collection)和映射(Map)的对象。它提供了一种简单的方法来访问容器中的元素,而无需了解容器的底层实现。通过使用迭代器,我们可以按顺序访问容器中的每个元素,而不必担心元素的实际存储方式。(后面会有例子展示)

  • 主要作用是担心使用者在遍历数据的时候有其他使用者对你的数据进行了恶意的修改,导致数据不一致出现风险,此时HashMap出现的错误是为了保护你的数据,这不是一种问题而是一种策略

  • Java中,迭代器实现了Iterator接口。该接口定义了以下方法:

  • hasNext():如果迭代器还有下一个元素,则返回true。
  • next():返回迭代器中的下一个元素。
  • remove():从迭代器指向的集合中删除迭代器返回的最后一个元素。

代码展示:

package chapter06;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class Collection_iterator {
public static void main(String[] args) throws Exception {
/*
* 要求: 获取下面Map中的key值随后循环遍历出Map中的key值,删除该Map中
* key = "b"的value值
* */

// TODO 集合 - Map
HashMap<String, Integer> map = new HashMap<String, Integer>();
// 插入数据
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);

Set<String> keys = map.keySet();

/*
* 这段代码会报错,因为我们在删除了Map中的"b"这一项的时候,这一个步骤是没问题的,
* 问题就出现在 上面的 Set 那里,因为我们都知道,上面的Set是通过Map来获取它的
* key值的,那此时你删除了Map中的数据,Set是不知道的,而此时你循环的是Set中的值(keys)
* 此时就会报错了,解决办法就是你需要让Set也知道Map中的长度数据发生了变化
* */
// ---------------- 这段代码会报错 -------------------
// for (String key : keys) {
// if ( "c".equals(key) ) {
// map.remove("b");
// // map.put("b",2) // 修改数据是不会报错的
// }
// System.out.println(map.get(key)); // 报错
// }
// ------------------------------------------------

// TODO 迭代器
// 使用迭代器,将Set(keys)值变成一个迭代器
Iterator<String> iterator = keys.iterator();
// hasNext方法用于判断是否存在下一条数据
while (iterator.hasNext()) { // 存在下一条数据
// 获取下一条数据
String key = iterator.next(); // 获取下一条数据
if("b".equals(key)) {
// remove方法只能对当前数据删除
iterator.remove(); // 移除当前这条数据
}
System.out.println(map.get(key)); // 1 , null , 3
}
/*
* 相当于每一条数据循环之前都判断一下是否存在下一条数据,如果存在,则获取这条数据
* 对比目标数据,如果符合条件,则删除该条数据
* */
}
}

工具类

  • 这里就展示Arrays的工具类
package chapter06;

import java.util.Arrays; // 导入工具类
import java.util.List;

public class Collection_util {
public static void main(String[] args) throws Exception {

// TODO 集合 - Arrays
int[] is = {3,5,2,1,4};
int[] is1 = {1,2,3,4,5};
int[] is2 = {1,2,3,4,5,6};
System.out.println(Arrays.toString(is)); // 将数组转化为字符串形式 [3,5,2,1,4]
System.out.println(is);// 输出 hashcode 存放地址

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5); // 将数组转化为List集合

// 排序(默认为升序)
Arrays.sort(is); // 1,2,3,4,5
System.out.println(Arrays.toString(is)); // [1,2,3,4,5]

// 二分查找法,排序后的数组
System.out.println(Arrays.binarySearch(is, 5)); // 4 (0-4)

// 数组的比较
System.out.println(Arrays.equals(is2, is1)); // false[顺序不一致]
System.out.println(Arrays.equals(is1, is)); // true[顺序不致]
// 只对比数组的前5项
System.out.println(Arrays.equals(is2, 0, 5, is1, 0, 5));// true
}
}