注意集合里面只能存放引用数据类型的数据,基本数据类型的需要使用其包装类!
Map 双列集合
重要方法:
Map集合的3种遍历方式:
方式1:keySet()获取健名称,然后循环健名,再用get方法获取值
方式2:entrySet() 方法获取键值对遍历
方式3:lambda forEach 方式【内部源码其实也是用的 entrySet() 遍历】
注意:方式1和方式2都是获取的 set 集合,那么可以使用 Collection 集合的三种遍历方式来遍历 set (iterator 迭代器遍历、增强for遍历、forEach Lambda表达式遍历)
package com.集合重点;
import java.util.*;
public class Map遍历Demo {
public static void main(String[] args) {
//map 基础api
baseMapApi();
System.out.println();
//map 循环的几种方式
mapLoopMethod();
}
// map 循环的几种方式
private static void mapLoopMethod() {
System.out.println("------------- map 循环------------");
Map<String, String> mp = new HashMap<>();
mp.put("001", "张三");
mp.put("002", "李四");
//mp.put("002", "王五"); // 健名相同,后面的覆盖前面的
mp.put("003", "李四222");
System.out.println("----- 获取所有键名----");
Set<String> mpKeys = mp.keySet(); // 获取所有键名
for (String x : mpKeys) {
System.out.println(x);
}
System.out.println("----- 获取所有值----");
Collection<String> mpValues = mp.values();
for (String x : mpValues) {
System.out.println(x);
}
// map集合遍历
System.out.println("----- 1.map集合遍历1 键找值 ----");
Set<String> mks = mp.keySet(); // 获取所有键名 - 因为是set集合,可以使用集合的3种遍历方式
System.out.println("----- 1.1.键找值:增强for方式 ----");
for (String x : mks) {
String s = mp.get(x);
System.out.println(x + ":" + s);
}
System.out.println("----- 1.2.键找值:迭代器方式 ----");
Iterator<String> keysIterator = mks.iterator();
while (keysIterator.hasNext()) {
String key = keysIterator.next();
String v = mp.get(key);
System.out.println(key + ":" + v);
}
System.out.println("----- 1.3.键找值:lambda方式 ----");
mks.forEach(System.out::println);
System.out.println("----- 2.map集合遍历2 ----");
Set<Map.Entry<String, String>> entries = mp.entrySet(); // entrySet返回的是key:value的集合 - 因为是set集合,可以使用集合的3种遍历方式
for (Map.Entry<String, String> me : entries) {
String key = me.getKey();
String value = me.getValue();
System.out.println(key + ":" + value);
}
System.out.println("----- 3.map集合遍历3 map直接使用 lambda 的方式 ----");
mp.forEach((k,v)->{
System.out.println(k + ":" + v);
});
}
// map 基础api
private static void baseMapApi() {
System.out.println("-----------Map 基础api使用----------");
Map<String, String> mp = new HashMap<>();
mp.put("001", "张三");
mp.put("002", "李四");
mp.put("002", "王五"); // 健名相同,后面的覆盖前面的
mp.put("003", "李四222");
System.out.println(mp);
System.out.println("mp.remove " + mp.remove("003"));
; // 根据key删除,并返回删除项
System.out.println("mp.containsKey " + mp.containsKey("001"));
System.out.println("mp.containsValue " + mp.containsValue("张三"));
System.out.println("mp.size " + mp.size());
System.out.println("mp.isEmpty " + mp.isEmpty());
System.out.println("mp.get " + mp.get("001"));
/* mp.clear(); // 清空
System.out.println("清空:"+mp);*/
}
}
特别注意:添加自定义对象时(比如自己写的Student类),HashMap 和 LinkedHashMap 需要重写 hashCode 和equals 方法,TreeMap需要重写 compareTo 方法
1.Map -> HashMap
特点:无序、不重复(key)、无索引。底层是数组+加链表+红黑树的哈希表结构。
1.1 Map -> HashMap -> LinkedHashMap
特点:有序、不重复、无索引
2.Map -> TreeMap
特点:不重复、无索引、可排序
排序规则方式一:实现Comparable接口,指定比较规则。
image.png
排序规则方式二:创建集合时传递比较器对象,指定比较规则。
image.png
比较方法返回值的特点:
- 负数:表示当前要添加的元素是小的,存左边
- 正数:表示当前要添加的元素是大的,存右边
- 0:表示当前要添加的元素已经存在,舍弃(就是用这点来去重的!)
image.png
3.Map -> Properties
在java里面 properties 配置文件用于存储键值对数据,Map集合里面有个专门的数据类型用来对这种数据进行读写 - Properties
类,因为是Map的子类,所以Map的三种遍历方式也可以使用。
常用方法如下:
package com.IO流;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Propertys和IO流结合使用Demo {
public static void main(String[] args) throws IOException {
// 结合IO流使用
storeData();
loadData();
// 简单使用
simpleUse();
simpleUseMap();
}
// 把集合数据读取出来
private static void loadData() throws IOException {
Properties prop = new Properties();
FileReader fr = new FileReader("idea_test\\info.properties", StandardCharsets.UTF_8);
prop.load(fr); // 读取数据到集合中
fr.close();
System.out.println(prop);
}
// 把集合数据写入到文件
private static void storeData() throws IOException {
Properties prop = new Properties();
prop.setProperty("0001", "张三丰");
prop.setProperty("0002", "孙悟空");
prop.setProperty("0003", "贝吉塔");
FileWriter fw = new FileWriter("idea_test\\info.properties");
prop.store(fw, "注释信息"); // 写数据到文件中
fw.close();
}
// 简单使用
private static void simpleUse() {
System.out.println("---------- Properties 特有方法 -----------");
Properties prop = new Properties();
prop.setProperty("0001", "张三丰");
prop.setProperty("0002", "孙悟空");
prop.setProperty("0003", "贝吉塔");
Set<String> strings = prop.stringPropertyNames();
for (String x : strings) {
String value = prop.getProperty(x);
System.out.println(x + ":" + value);
}
}
// 作为map的使用
private static void simpleUseMap() {
System.out.println("---------- Properties 作为map的使用 -----------");
Properties prop = new Properties();
prop.put("0001", "张三丰");
prop.put("0002", "孙悟空");
prop.put("0003", "贝吉塔");
// 循环1:keySet方式
System.out.println("----------- 循环1:keySet方式 -----------");
Set<Object> objects = prop.keySet();
for (Object x : objects) {
Object value = prop.get(x);
System.out.println(x + ":" + value);
}
// 循环2:entrySet方式
System.out.println("----------- 循环2:entrySet方式 -----------");
Set<Map.Entry<Object, Object>> entries = prop.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + ":" + value);
}
// 循环3:forEach方式
System.out.println("----------- 循环3:forEach方式 -----------");
prop.forEach((k, v) -> {
System.out.println(k + ":" + v);
});
}
}
可以看到中文变成了乱码,原因是由于Java的Properties类默认使用ISO-8859-1编码方式读取Properties文件,而不是我们期望的UTF-8编码方式。因此,当Properties文件中包含中文字符时,会导致乱码问题。
当我们读取的时候需要指定utf-8 new FileReader(文件路径, StandardCharsets.UTF_8)
,这样程序里面才会解析正常。
Properties 里面最重要的有两个特有方法,load 和 store,掌握这两个就行了:
总结
其实 HashSet、LinkedHashSet、TreeSet 内部其实是分别调用的 HashMap、LinkedHashMap、TreeMap类来实现对象,只不过一边是单列集合,一边是双列集合而已,只需要记一边就行了,这样不容易搞混淆。
参考:黑马java教程