1 IO流
继承结构:
in/out相对于程序而言的输入(读取)和输出(写出)的过程。
java.io包:
字节流:针对二进制文件
InputStream
--FileInputStream
--BufferedInputStream
--ObjectInputStream
OutputStream
--FileOutputStream
--BufferedOutputStream
--ObjectOutputStream
字符流:针对文本文件。读写容易发生乱码现象,在读写时最好指定编码集为utf-8
Writer
--BufferedWriter
--OutputStreamWriter
Reader
--BufferedReader
--InputStreamReader
--PrintWriter/PrintStream
1.1 File类
概述:
封装一个磁盘路径字符串,对这个路径可以执行一次操作。
可以用来封装文件路径、文件夹路径、不存在的路径。
创建对象:
//1,新建File对象
File file =new File("D:\\me\\1.txt");
常用的方法:
//2,常用方法
//文件,文件夹属性
System.out.println(file.length());//0--获取文件的字节
System.out.println(file.exists());//true--判断文件是否存在,存在返回true
System.out.println(file.isFile());//true--判断是否是一个文件,是的返回true
System.out.println(file.isDirectory());//false--判断是不是一个文件夹,是的返回true
System.out.println(file.getName());//1.txt--获取文件名
System.out.println(file.getParent());//D:\me--获取父路径
System.out.println(file.getAbsolutePath());//D:\me\1.txt--获取完整的路径
//创建,删除
file = new File("D:\\me\\2.txt");//新建文件,成功true
System.out.println(file.createNewFile());//新建不存在的文件
file = new File("D:\\me\\p");
System.out.println(file.mkdir());//新建一层不存在的文件夹
file = new File("D:\\me\\q\\y");
System.out.println(file.mkdirs());//新建多层不存在的文件夹
file = new File("D:\\me\\q\\y");
System.out.println(file.delete());//删除文件或者空的文件夹
//文件夹列表
file = new File("D:\\me");
//[1.txt, 2.txt, m, n, p, q],获取文件资源名称
String[] strs = file.list();
//[D:\me\1.txt, D:\me\2.txt, D:\me\m, D:\me\n, D:\me\p, D:\me\q],获取文件资源路径
File[] fs = file.listFiles();
1.2 字节流
字节流是由字节组成的,字符流是由字符组成的. Java里字符由两个字节组成.字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据。
流式传输主要指将整个音频和视频及三维媒体等多媒体文件经过特定的压缩方式解析成一个个压缩包,由视频服务器向用户计算机顺序或实时传送。在采用流式传输方式的系统中,用户不必像采用下载方式那样等到整个文件全部下载完毕,而是只需经过几秒或几十秒的启动延时即可在用户的计算机上利用解压设备对压缩的A/V、3D等多媒体文件解压后进行播放和观看。此时多媒体文件的剩余部分将在后台的服务器内继续下载。
1.2.1 字节流读取
InputStream抽象类:
此抽象类是表示字节输入流的所有类的超类/抽象类。
常用方法:
abstract int read()
从输入流中读取数据的下一个字节。
int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
void close()
关闭此输入流并释放与该流关联的所有系统资源。
FileInputStream子类:
直接插在文件上,直接读取文件数据。
创建对象:
FileInputStream(File file)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String pathname)
通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
BufferedInputStream子类:
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组(默认8M大小)。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
创建对象:
BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
1.2.2 字节流写出
OutputStream抽象类:
此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。
常用方法:
void close()
关闭此输出流并释放与此流有关的所有系统资源。
void flush()
刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b)
将指定的字节写入此输出流。
FileOutputStream子类:
直接插在文件上,直接写出文件数据
创建对象:
FileOutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(File file, boolean append) –追加
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
BufferedOutputStream子类:
该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
创建对象:
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流
测试读写:
public static void main(String[] args) {
System.out.println("请你输入源文件路径");
String frompath = new Scanner(System.in).nextLine();
File from = new File(frompath);
System.out.println("请你输入目标文件路径");
String topath = new Scanner(System.in).nextLine();
File to =new File(topath);
//复制
copyof(from,to);
System.out.println("文件复制成功");
}
private static void copyof(File from, File to) {
//1,创建读写对象
InputStream in =null;
OutputStream out =null;
try {
in = new BufferedInputStream(new FileInputStream(from));
out = new BufferedOutputStream(new FileOutputStream(to));
//2.1,批量读写
int a = 0;//定义变量,记录读取到的数据
byte [] bs = new byte[8192];
while((a = in.read(bs))!=-1) {//只要有数据就一直读
out.write(bs);//把读到的文件写出去
}
// //2,开始读写
// int a = 0;//定义变量,记录读取到的数据
// while((a = in.read())!=-1) {//只要有数据就一直读
// out.write(a);//把读到的文件写出去
// }
} catch (IOException e) {e.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.3 字符流
常用于处理纯文本数据。
1.3.1 字符流读取
Reader抽象类:
用于读取字符流的抽象类。
常用方法:
int read()
读取单个字符。
int read(char[] cbuf)
将字符读入数组。
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。
int read(CharBuffer target)
试图将字符读入指定的字符缓冲区。
abstract void close()
关闭该流并释放与之关联的所有资源。
FileReader子类:
用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。
创建对象:
FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。
FileReader(File file)
在给定从中读取数据的 File 的情况下创建一个新 FileReader。
InputStreamReader子类:
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
创建对象
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
InputStreamReader(InputStream in)
创建一个使用默认字符集的 InputStreamReader。
BufferedReader子类:
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
创建对象:
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
1.3.2 字符流写出
Writer抽象类:
写入字符流的抽象类。
常用方法:
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str)
写入字符串。
void write(String str, int off, int len)
写入字符串的某一部分。
abstract void close()
关闭此流,但要先刷新它。
FileWriter子类:
用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。
创建对象:
FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
OutputStreamWriter子类:
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
创建对象:
OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。
OutputStreamWriter(OutputStream out)
创建使用默认字符编码的 OutputStreamWriter。
BufferedWriter子类:
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
创建对象:
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
1.4 序列化和反序列化
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
1、序列化:利用ObjectOutputStream,对象的信息,按固定格式转成一串字节值输出并持久保存到磁盘化。
2、反序列化:利用ObjectInputStream,读取磁盘中序列化数据,重新恢复对象。
注意:
1、 需要序列化的文件必须实现Serializable接口以启用其序列化功能。
2、 每个被序列化的文件都有一个唯一id,如果没有添加编译器会根据类的定义信息计算产生一个版本号。
//序列化:就是把java对象保存在磁盘中
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream( "D:\\teach\\a\\student.txt"));
Student s = new Student("张三",20,"成都");
os.writeObject(s);//序列化,把Student对象信息保存到指定文件中
os.close();//关闭输出资源
//反序列化:从磁盘读到程序里
ObjectInputStream in =new ObjectInputStream(
new FileInputStream("D:\\teach\\a\\student.txt"));
//反序列化,把文件里的数据读到程序中,封装成对象,默认是Object
Object obj =in.readObject();
System.out.println(obj);
1.5 编码转换流
用来作为桥梁,把字节流转成字符流的桥梁。用来解决字符流读写乱码问题。
工具类:
OutputStreamWriter:是字节流通向字符流的桥梁
--OutputStreamWriter(OutputStream out, String charsetName)
--OutputStreamWriter(OutputStream out)
InputStreamReader:是字节流通向字符流的桥梁
--InputStreamReader(InputStream in)
--InputStreamReader(InputStream in, String charsetName)
1.6 BIO、NIO、AIO的区别
阻塞IO,BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
非阻塞IO,NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
异步IO,AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它 AIO(Asynchronous IO),异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。但目前还不够成熟,应用不多。
2 泛型
作用1:通过泛型的语法定义,约束集合元素的类型,进行安全检查,把错误显示在编译期。
作用2:代码通用性更强。
泛型可以在接口、方法、返回值上使用:
java.util.List泛型接口/类:
public interface Collection {}
泛型方法的声明:
public void print(E e) {}
在方法返回值前声明了一个表示后面出现的E是泛型,而不是普通的java变量。
3 集合
为了解决多个数据的存储。现有的容器是数组。
数组的优势:元素都是下标,可以快速查询。
数组的缺点:数据类型都是统一的,遍历方式单一(下标)。
为了解决数组的缺陷,又产生了集合,可以存储多个类型的数据,遍历方式很丰富。
3.1 Collection接口
创建对象:
Collection c = new ArrayList<>();
Collection c = new ArrayList ();
调用方法:
boolean add(E e):添加元素。
boolean addAll(Collection c):把小集合添加到大集合中 。
boolean contains(Object o) : 如果此 collection 包含指定的元素,则返回 true。
boolean isEmpty() :如果此 collection 没有元素,则返回 true。
Iterator iterator():返回在此 collection 的元素上进行迭代的迭代器。
boolean hasNext() :如果仍有元素可以迭代,则返回 true。
E next() :返回迭代的下一个元素。
void remove() :从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
boolean remove(Object o) :从此 collection 中移除指定元素的单个实例。
int size() :返回此 collection 中的元素数。
Objec[] toArray():返回对象数组
测试 :
//1,创建接口
Collection c = new ArrayList<>();
//2,调用接口
c.add(456); // 集合添加元素 456
System.out.println(c.add(123));//true 集合添加元素是否成功
System.out.println(c);//[456, 123] 输出集合c里的元素
// c.clear();// 移除此 collection 中的所有元素
System.out.println(c.contains(123));//true 集合是否包含123
System.out.println(c.equals("456,123"));//false 比较两个对象是否相等
System.out.println(c.hashCode());//15220 获取哈希码值
System.out.println(c.isEmpty());//false 判断是否为空
System.out.println(c.remove(12));//false 从此 collection 中移除指定元素的单个实例,如果存在的话
System.out.println(c.size());//2 返回此 collection 中的元素数。
// Object[] --toArray() 返回包含此 collection 中所有元素的数组。
Object[] o = c.toArray();//把集合里的元素,存入Object[]里
System.out.println(Arrays.toString(o));
//集合间的操作
Collection c1 = new ArrayList<>();
c1.add(1);
c1.add(2);
System.out.println(c.addAll(c1));//true 把c1加到c中去
System.out.println(c);//[456, 123, 1, 2]
System.out.println(c.containsAll(c1));//true 判断c中是否有c1的数据
// System.out.println(c.removeAll(c1));//true 移除c和c1中都有的--取差
// System.out.println(c);//[456, 123]
System.out.println(c.retainAll(c1));//true 保留c和c1中都有的元素--取交集
System.out.println(c);//[1, 2]
//迭代集合Iterator -- iterator() 返回在此 collection 的元素上进行迭代的迭代器。
Iterator it = c.iterator();
while(it.hasNext()) {//hasNext() 用来判断有没有下一个元素,有就返回true
Integer i = it.next();//next();获取元素
System.out.println(i);//1 2
}
3.1.1 List接口
概述:有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
特点:1、 数据有序;2、 允许存放重复元素;3、 元素都有索引
调用方法:
ListIterator listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
ListIterator listIterator(int index)
返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(int index, Collection extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
List subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
E get(int index)
返回列表中指定位置的元素。
int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
测试:
//List接口的特点
System.out.println(l);//[1.1, 3.1, 3.1, null, null, 5.5, 6.5]
l.add(2, 9.9);//在指定的索引处,添加指定的数据
System.out.println(l);//[1.1, 3.1, 9.9, 3.1, null, null, 5.5, 6.5]
System.out.println(l.get(0));//1.1 获取索引值处对应的元素值
System.out.println(l.indexOf(null));//4 获取null第一次出现的索引值
System.out.println(l.lastIndexOf(null));//5 获取null最后一次出现的索引值
System.out.println(l.remove(5));//移除索引值对应的元素
System.out.println(l.set(5, 10.0));//把索引值5的元素设置成10.0
System.out.println(l);//[1.1, 3.1, 9.9, 3.1, null, 10.0, 6.5]
List l2=l.subList(2, 6);//截取List集合,含头不含尾
System.out.println(l2);//[9.9, 3.1, null, 10.0]
//迭代List集合
// Iterator -- iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器。 --返回父接口
// ListIterator -- listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 --返回子接口 --可以向后遍历也提供了逆向遍历
ListIterator li= l2.listIterator();
//顺序遍历
while(li.hasNext()) {//判断有没有下一个元素
Double db = li.next();//获取下一个元素
System.out.println(db);
}
//逆向遍历--必须先顺序遍历完才能逆向--了解
while(li.hasPrevious()) {//判断有没有前一个元素
Double db = li.previous();//获取前一个元素
System.out.println(db);
}
// ListIterator -- listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
//迭代List集合方式3
for(int i1 =0; i1
3.1.1.1 ArrayList实现类
概述:
1) 存在于java.util包中。
2) 内部用数组存放数据,封装了数组的操作,每个对象都有下标。
3) 内部数组默认初始容量是10。如果不够会以1.5倍容量增长。
4) 查询快,增删数据效率会降低。
3.1.1.2 LinkedList实现类
概述:双向链表,两端效率高。底层就是数组和链表实现的。
测试:
//LinkedList的特有方法--针对首尾元素
list.addFirst(0);//添加首元素
list.addLast(9);//添加尾元素[0, 1, 2, 3, 4, 5, 9]
System.out.println(list.getFirst());//0 获取首元素
System.out.println(list.getLast());//9 获取尾元素
System.out.println(list.removeFirst());//0 移除首元素
System.out.println(list.removeLast());//9 移除尾元素[1, 2, 3, 4, 5]
数组和链表区别
List是一个接口,它有两个常用的子类,ArrayList和LinkedList,看名字就可以看得出一种是基于数组实现另一个是基于链表实现的。
数组ArrayList遍历快,因为存储空间连续;链表LinkedList遍历慢,因为存储空间不连续,要去通过指针定位下一个元素,所以链表遍历慢。
数组插入元素和删除元素需要重新申请内存,然后将拼接结果保存进去,成本很高。例如有100个值,中间插入一个元素,需要数组重新拷贝。而这个动作对链表来说,太轻松了,改变一下相邻两个元素的指针即可。所以链表的插入和修改元素时性能非常高。
实际开发就根据它们各自不同的特点来匹配对应业务的特点。业务一次赋值,不会改变,顺序遍历,就采用数组;业务频繁变化,有新增,有删除,则链表更加适合。
3.1.2 Set接口
概述:
一个不包含重复元素的 collection。并且最多包含一个 null 元素。
数据无序(因为set集合没有下标)。
由于集合中的元素不可以重复。常用于给数据去重。
特点:
HashSet:底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中。当然K仍然不许重复。
TreeSet:底层就是TreeMap,也是红黑树的形式,便于查找数据。
共性方法同Collection接口方法。
3.1.2.1 TreeSet实现类
3.1.2.2 HashSet实现类
概述:
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
特点:数据无序+不能重复+存一个null+没有下标
3.2 Map接口
概述:
Map
类型参数:
K - 此映射所维护的键的类型
V - 映射值的类型
--将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
--Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺序。某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类。
特点:
--实现类HashMap
--键值对 的数据结构
--键不能重复 ----会被覆盖
--HashMap 是无序的
--Tree 是有序的
共性方法:
void clear()
从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
Set> entrySet()
返回此映射中包含的映射关系的 Set 视图。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
V get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int hashCode()
返回此映射的哈希码值。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
Set keySet()
返回此映射中包含的键的 Set 视图。
V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int size()
返回此映射中的键-值映射关系数。
Collection values()
返回此映射中包含的值的 Collection 视图。
测试:
//1,创建对象
Map map=new HashMap<>();
//2,调用方法
map.put(9530, "石榴姐");//
map.put(9528, "如花");
map.put(9527, "唐伯虎");
map.put(9529, "秋香");
map.put(9529, "冬香");//
//特点:无序+key重复的话,value会被覆盖
// map.clear();//清空集合
System.out.println(map.containsKey(9527));//true 是否包含9527K
System.out.println(map.containsValue("唐伯虎"));//true 是否包含唐伯虎V
System.out.println(map.equals("唐伯虎"));//false
System.out.println(map.get(9527));//唐伯虎 获取K的V
System.out.println(map.hashCode());//53373144
System.out.println(map.isEmpty());//false 是否为空
System.out.println(map.remove(9528));//如花 移除K-V,返回V
System.out.println(map.size());//3 获取Map的长度,键对值得数量
// void putAll(Map extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中
Map map2=new HashMap<>();
map2.put(100, "张三丰");
map2.putAll(map);//{100=张三丰, 9527=唐伯虎, 9529=冬香, 9530=石榴姐}
//迭代Map
// Set keySet() 返回此映射中包含的键的 Set 视图。
Set set = map2.keySet();
//迭代器 Iterator
Iterator it = set.iterator();
while(it.hasNext()) {
Integer key = it.next();
String value = map2.get(key);
System.out.println(key+"的value是"+value);
}
//改造 foreach 语法:for(遍历得到的数据的类型 变量名 :想要遍历的容器){循环体}
for(Integer key:set) {
//拿着key回map2取value
String value = map2.get(key);
System.out.println(key+value);
}
Collection a =map2.values(); //Map的V生成Collection集合
System.out.println(a);//[张三丰, 唐伯虎, 冬香, 石榴姐]
// Set> entrySet() 返回此映射中包含的映射关系的 键值对。
Set> set1 =map2.entrySet();
System.out.println(set1);//[100=张三丰, 9527=唐伯虎, 9529=冬香, 9530=石榴姐]
//遍历set得到每个Entry对象
for(Map.Entry entry:set1) {
Integer key = entry.getKey();// K getKey() 返回与此项对应的键。
String value = entry.getValue();//V getValue() 返回与此项对应的值。
System.out.println(key+"=="+value);
}
3.2.1 HashMap
概述:
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。
HashMap底层是一个Entry数组,当存放数据时会根据hash算法计算数据的存放位置。算法:hash(key)%n,n就是数组的长度。
当计算的位置没有数据时,就直接存放,当计算的位置有数据时也就是发生hash冲突的时候/hash碰撞时,采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。
3.2.2 TreeMap
3.3 Collections工具类
共性方法:
static boolean addAll(Collection super T> c, T... elements)
将所有指定元素添加到指定 collection 中。
static > T max(Collection extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
static > T min(Collection extends T> coll)
根据元素的自然顺序 返回给定 collection 的最小元素。
static boolean replaceAll(List list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static void reverse(List> list)
反转指定列表中元素的顺序。
排序:
static > void sort(List list)
根据元素的自然顺序 对指定列表按升序进行排序。
static void sort(List list, Comparator super T> c)
根据指定比较器产生的顺序对指定列表进行排序。