目录
一.Map集合:
1.1 Map集合概述:
- Map集合是一种双列集合,是一种键-值对集合,集合中每个元素都包含一个键对象,一个值对象。
注意点:键不可以重复,是唯一的。而值可以重复,可以通过键找到对应的值
- 个人理解:Map集合中的键,很像下标,在List中下标是整数,而Map集合中的键可以是任意类型的元素。下标是唯一,键也是唯一。可以通过键找到与之对应的值。
- 我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即
java.util.Map
接口。
注意点:
1.Map集合中的值只能通过对应键找到,不能直接查找对应的值。
2.键是唯一的,值可以重复
1.2 Map集合遍历:
Map集合有两种遍历方式:
1.键找值方式。通过元素中的键,获取键所对应的值2.键值对方式。即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
方式一.键找值方式:
步骤:1.用keySet获取到Map中所有键,并且将所有的键放大set集合中存储。
2.遍历set集合中每一个键值。
3.通过键值使用get方法获取到每个键值对应的值。
代码演示:
Set set = hashMap1.keySet();
for (Object set2 : set) {
System.out.println(set2);
}
方式二:键值对方式:
步骤:
使用entryset()获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。
遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
通过键值对(Entry)对象调用getkey(),getvalue(),获取Entry对象中的键与值。
什么是Entry键值对对象:
Map
中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map
中是一一对应关系,这一对对象又称做Map
中的一个Entry(项)
。Entry
将键值对的对应关系封装成了对象。即键值对对象。
获取Entry对象的方法:
public Set<Map.Entry<K.V>> entrySet() 获取到Map集合中所有的键值对对象的集合(Set集合)。
代码演示:
/*
方式二
*/
Set<Map.Entry<Object,Object>> set3 = hashMap.entrySet();
for (Map.Entry<Object,Object> entry:set3) {
System.out.println("键:"+entry.getKey()+"值"+entry.getValue());
}
2.Map集合与collection集合对比:
- 两者都是Java.util包下面的接口,属于平级关系。
- Map集合是双列集合,存储的元素都是成对出现的,Map元素的键是唯一的,值是可以重复。
- Collection集合是单列集合,存储的元素都是单独出现的,Collection接口下面的Set是元素唯一的, List集合中元素是可以重复的。
通过下面这张图更好的展示Map集合与collection集合的关系以及他们的实现类:
3.实现类的使用以及常用方法
实现类实现Map接口中抽象方法,所以方法基本上没有什么变化。只是实现类底层的实现不同。
1、添加功能:
put(K key,V value) 将指定的值与该映射中的指定键添加到集合中
2、删除功能:
remove(Object key) 如果存在,从该map集合中删除该键的元素
void clear() 从该map集合中删除所有的元素
3、长度功能:
int size() 获取元素的数量
4. 获取元素:
get(Object key) 根据指定的key获取对应的value
5.判断功能:
boolean containsKey(Object key)
boolean containsValue(Object value)
public class MapTest {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
HashMap hashMap1 = new HashMap();
//添加元素
hashMap.put("数字1:", 1);
hashMap.put("数字2:", 2);
hashMap.put("数字2:", 3);
hashMap.put("数字3:", 99);
hashMap.put("数字4:", 4);
hashMap.put("数字5:", null);
Object a=hashMap.get("数字1:");
//输出的是键值
System.out.println(a);
//移除元素
hashMap.remove("数字5:");
System.out.println("===========");
//判断功能
boolean b = hashMap.containsKey("数字6:");
System.out.println("集合是否存在这个元素:"+b);
//获取元素:
Object o = hashMap.get("数字5:");
System.out.println("使用get获取到的元素:"+o);
hashMap.clear();
System.out.println(hashMap);
3.1 HashMap实现类:
底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。键的唯一性,需要覆盖hashCode方法,和equals方法
注意点
1.HashMap的存取顺序是不一致的,要使存取顺序一致,必须使用LinkedhashMap.
//添加元素
hashMap.put("数字1:", 1);
hashMap.put("数字2:", 2);
hashMap.put("数字2:", 3);
hashMap.put("数字3:", 99);
hashMap.put("数字4:", 4);
hashMap.put("数字5:", null);
//获取元素
Object a=hashMap.get("数字1:");
//输出的是键值
System.out.println(a);
//移除元素
hashMap.remove("数字5:");
System.out.println("===========");
//判断功能
boolean b = hashMap.containsKey("数字6:");
System.out.println("集合是否存在这个元素:"+b);
//获取元素:
Object o = hashMap.get("数字5:");
System.out.println("使用get获取到的元素:"+o);
Set set = hashMap.keySet();
for (Object set2 : set) {
System.out.println(set2);
}
输出结果:
2.使用hashmap存储自定义类型的元素时必须重写hashCode方法,和equals方法。
这个我在之前的博客已经解析过:为什么重写hashCode方法,和equals方法
3.2 TreeMap实现类:
TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;可以对元素的键进行排序。而他的排序可以分为自然排序和比较器排序。
自然排序:传入的key值实现了Comparable接口(String,Integer等都已经实现了Comparable接口,因此可以直接用)
//实现了Comeparable接口的自然比较
TreeMap treeMap1 = new TreeMap();
treeMap1.put("20",20);
treeMap1.put("30",30);
treeMap1.put("410",410);
treeMap1.put("10",10);
Set set1 = treeMap1.keySet();
for(Object set1s:set1){
System.out.println("键:"+set1s+",值:"+treeMap1.get(set1s));
}
System.out.println("------------");
比较器排序:创建TreeMap集合的时候指定比较器Comparator
使用比较器排序时注意以下几点:
1.要重写hashCode方法,和equals方法,避免重复元素。
2.实现Comparator排序器,按照自己的排序规则。
//实现Comparator比较器,进行比较。
TreeMap<Student,Object> treeMap = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int result = o1.age - o2.age;
if (result == 0) {
return o1.name.charAt(0) - o2.name.charAt(0);
}
return result;
}
});
treeMap.put(new Student("lisi",2000),"beijing");
treeMap.put(new Student("wangwu",200),"chengdu");
treeMap.put(new Student("zhangsan",21000),"hsanghai");
Set set = treeMap.keySet();
for(Object treemap:set){
System.out.println(treemap+"值为:"+treeMap.get(treemap));
class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return age == student.age &&
name.equals(student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", local='" + '\'' +
'}';
}
两者排序的结果:
二.File类:
1.File类概述:
File 类是 java.io 包中唯一代表磁盘文件本身的对象,也就是说,如果希望在程序中操作文件和目录,则都可以通过 File 类来完成
Java.io.File类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
File类就是描述文件或文件夹的,只要我们在Java中要操作文件或文件夹,就找File类。
注意点:
1.File类只能对持久设备上的文件和文件夹进行操作。它不能去操作文件中的数据。当要操作这个文件中的数据时使用这个IO流技术。所以IO流和File类一般是成双成对出现的。
1.2 构造方法:
File 类提供了如下三种形式构造方法。
- public File(String path):如果 path 是实际存在的路径,则该 File 对象表示的是目录;如果 path 是文件名,则该 File 对象表示的是文件。
public File(String parent, String child)
:从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child)
:从父抽象路径名和子路径名字符串创建新的 File实例。使用任意一个构造方法都可以创建一个 File 对象,然后调用其提供的方法对文件进行操作。但是我觉得这么做的原因是第二个和第三个方法增加了这个文件对象创建的多样性。我们的文件本来就是多样的,可以通过这个父路径,加上该路径下的子路径,创建一个不同的Flie对象。
构造方法根据文件或文件夹的路径名创建一个File对象。然后封装成File类的对象,但是这个字符串表示的路径或者文件到底是否存在,File类是不进行判断的。因为是否存在都不影响File类的创建。
注意:File类表示文件和目录路径名的抽象表示形式。那么该路径代表的文件或文件夹不一定存在。当我们要具体对该路径下的File类对象操作时,需要判断是否存在该文件或文件夹,否则有可能在遍历文件夹时报空指针异常,也有可能在其他操作出现异常。
代码演示:
//直接创建
File file = new File("F:\\训练\\javase\\课件\\day16File类");
//从父类目录以及子目录创建对象
String parent="F:\\训练\\javase\\课件";
String child="day16File类\\Excel";
File file2 = new File(parent, child);
//通过父级对象和子字符串创建:
File file3 = new File("F:\\训练\\javase\\课件");
String childdi="day16File类\\Excel\\123.txt";
File file4 = new File(file3, childdi);
2.File类常用方法:
获取方法:
1.public String getAbsolutePath():获取的当前调用这个方法的File对象的全路径(绝对路径或者真实路径) 返回的是路径的字符串。
绝对路径和相对路径的区别:绝对路径是带盘符,相对路径是相对的,一般不带盘符。
2.public String getPath():作用:获取到当前File类的对象中封装的内容,跟方法1差不多。
3.public String getName():作用:获取的是File类的对象中封装的文件或目录的最后一级名称,就是获取对象描绘的路径中最后一级的名称。
//直接创建
File file = new File("F:\\训练\\javase\\课件\\day16File类");
//获取该目录的绝对路径
String path=file.getAbsolutePath();
System.out.println(path);
//创建文件目录,已经创建了的文件会报false
boolean mkdir = file.mkdir();
System.out.println("创建文件目录:"+mkdir);
//获取到当前File类的对象中封装的内容
String path1 = file.getPath();
System.out.println("封装内容:"+path1);
判断方法:
4.public boolean exists():作用:是否存在 如果File类对象中的文件或者文件夹在硬盘上存在 返回 true ,否则返回false;
5.public boolean isDirectory():作用:判断是否是文件夹 如果是文件夹 返回 true 否则返回false;
6.public boolean isFile():作用:判断是否是文件 如果是文件 返回 true , 否则返回false;
7.public boolean createNewFile():作用 :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
//创建文件:没有找到对应的文件夹,失败抛出异常。
boolean newFile = file.createNewFile();
//判断这个文件是否存在:
boolean exist1=file.exists();
System.out.println("文件是否存在:"+exist1);
//文件夹是否存在:
boolean isexst1=file.isDirectory();
System.out.println("文件夹是否存在:"+isexst1);
删除创建方法:
8.delete方法,如果此File表示目录,则目录必须为空才能删除。2.函数的删除不走回收站。谨慎使用。
9.public boolean mkdir():创建由此File表示的目录。
10.public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录。
//删除文件目录:
boolean delete = file.delete();
System.out.println("删除文件目录:"+delete);
//创建文件:没有找到对应的文件夹,失败抛出异常。
boolean newFile = file.createNewFile();
//创建文件目录,已经创建了的文件会报false
boolean mkdir = file.mkdir();
System.out.println("创建文件目录:"+mkdir);
列举方法:
11.public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录。
12.public File[] listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录。
注意:list返回的是String数组,里面装的是String。而listfiles装的是file数组。里面是File对象。
//h获取当前文件夹的所有目录:必须是实际存在的否则或报错
File[] files = file.listFiles();
for (File file1:files) {
System.out.println("使用listFiles获取所有文件夹:"+file1);
}
//获取当前文件夹的目录:返回一个String数组
int count=0;
String[] name=file.list();
for(String names:name){
count++;
System.out.println("文件目录含有:"+names);
}
System.out.println("该文件夹下有"+count+"个文件夹。");
三.递归:
1.递归概述:
明天写完,呜呜太晚了。