集合:
Collention
单列集合分为list和set
双列集合是Map
Collection概述:
- 是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现
boolean add(E e):添加元素
boolean remove(Object o):从集合中移除指定的元素
boolean removeif(Object o):根据条件进行删除
void clear():清空集合
boolean contains(Object o):判断集合中是否存在指定的元素
boolean isEmpty():判断集合是否为空
int size():集合的长度
Collection集合的遍历
Iterator:迭代器,集合的专用遍历方式
-
Iterator iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
-
E next():获取当前位置的元素,将迭代器对象移向下一个
-
loolean hasNext():判断当前位置是否有元素可以被取出来
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
//获得迭代器的对象
Iterator<String> iterator = list.iterator();
/*System.out.println(iterator.hasNext());
System.out.println(iterator.next());*/
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if ("b".equals(next)){
iterator.remove();
}
}
System.out.println(list);
}
增强for
格式:
for(元素数据类型 变量名:数组或者集合){
}
修改第三方变量的值不会影响集合中的元素
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
for (String s : list){
System.out.println(s);
}
}
List
特点概述:
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置。
- 与set不同list通常允许重复的元素
有序 有索引 可重复
常用实现类
ArrayList,LinkedList,
ArrayList:底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,查询慢,增删快
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.println(s);
}
}
linkedList特有的功能
- public void addFirst(E e):在该列表开头插入指定的元素
- public void addLast(E e):将指定的元素追加到此列表末尾
- public E getFirst():返回此列表中的第一个元素
- public E getLast():返回此列表中的最后一个元素
- public E remove():从此列表中删除并返回第一个元素
- public E removeLast():从此列表中删除并返回最后一个元素
set集合
常用实现类
HashSet
-
特点
- 去重复
-
构造方法
- 空参数构造方法
- 带Collection参数的构造方法
TreeSet
- 不包含重复元素的集合
- 没有带索引的方法
- 可以将元素按照规则进行排序
想要使用TreeSet需要制定排序规则
自然排序Comparable的使用:
- 使用空参构造创建TreeSet集合
- 自定义的Student类实现Comparable接口
- 重写里面的compareTo方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YNdZPkRu-1644923457301)(java.assets/P9E%7BW%7B%7BIQMVE%5B%7BSZW$FCVF8.png)]
@Override
public int compareTo(Student o) {
int result = this.age - o.age;
result = result == 0 ? this.name.compareTo(o.getName()) : result;
return result;
}
//如果返回值为负数,表示当前存入的元素是小值,存左边,如果返回值为0,表示重复了,不存,返回正数,表示当前存入的元素是大值,存右边
比较器排序:
- TreeSet的带参构造方法使用的比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件来写
public static void main(String[] args) {
//使用比较器存入 t1是要存入的那个元素 t2已经存入的元素
TreeSet<Teacher> set = new TreeSet<>((t1,t2)->{
int i = t2.getAge() - t1.getAge();
return i == 0 ? t2.getName().compareTo(t1.getName()) : i;
});
Teacher t1 = new Teacher("dlrb",18);
Teacher t2 = new Teacher("glnz",19);
Teacher t3 = new Teacher("mezh",18);
set.add(t1);
set.add(t2);
set.add(t3);
System.out.println(set);
}
两种比较方式小结:
自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序。
比较器排序:创建TreeSet对象的时候传递comparator的实现类对象,重写compare方法,根据返回值进行排序。
常用方法
- 请参考Collection接口中的方法
数据结构二叉树:
ArrayList:数组结构
LinkedList:链表结构
TreeSet:树结构
-
二叉树
-
二叉查找树
-
平衡二叉树
-
红黑树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8NuJ1Bu8-1644923457308)(java.assets/VIK9I7$A1V8XPFH0%60MGF-16424100003152.png)]
二叉查找树:
- 每个节点上最多有两个子节点
- 每个节点的右子节点都是大于自己的
- 每个节点的左子节点都是小于自己的
平衡二叉树:
二叉树左右两个子树的高度差不超过1
任意节点的两个左右子树都是一个平衡树
hash值介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SkkPsZZL-1644923457308)(java.assets/image-20220108104209592.png)]
Hashset集合判断元素唯一性
- 依赖元素的hashCode方法和equals方法共同作用,缺一不可!!!
Map集合
概念
- Map集合是一种存储键值对数据的集合,且键不能重复;
特点
- 1:保存的是成对的数据;且键与值一一对应;
- 2:键不能重复
常用实现类
-
HashMap
-
特点
- hash表结构,键不能重复;
-
构造方法
- 使用空参数构造方法即可
-
-
TreeMap
-
特点
- 红黑树结构,键可以自动排序
-
构造方法
-
空参数构造方法
- 适用于自然排序
-
带比较器的构造方法
- 适用于自定义排序规则
-
-
常用方法
- put(k,v); 添加键值对,如果键重复,则修改键值对;
- get(k);根据k从map中获取对应的值;
- remove(k);根据k从map中删除对应的键值对
- size();获取map集合的长度;
- containsKey(key);判断集合中是否包含指定的key;
遍历方式1
- 1:利用keySet方法获取map中所有的键,组成一个单列集合set;
- 2:遍历set集合,从中获取每一个元素,这些元素就是map中的键;
- 3:利用map中的get(key)方法,获取对应的value;
遍历方式2
- 1:利用entrySet方法获取map中所有的键值对对象,组成一个单列集合set;
- 2:遍历set集合,从中获取每一个元素,这些元素就是map中的键值对对象;
- 3:利用键值对对象中的getKey()方法,和getValue()方法获取对应的键和值;
遍历方式3
-
概述
- 从JDK8开始,在map接口中添加了一个默认方法, forEach,有一个接口参数,无返回值;而接口中刚好只有一个抽象方法,所以可以使用lambda
-
格式
- map对象.forEach(lambda规则,处理key和vlaue即可);
红黑树
概述
- 是一种自平衡二叉查找树,在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
规则
-
- 所有节点要么是红色要么是黑色。
-
- 根节点是黑色。
- 3.所有叶子都是黑色。(叶子是NIL节点)
-
- 不能有两个连续的红色节点
- 5…从根节点到其每个叶子的所有路径都包含相同数目的黑色节点。
添加节点
-
1.添加节点时,默认为红色,效率高
-
2:如果添加到根节点位置则直接添加,然后变为黑色
-
3:添加到根节点位置非根节点位置
-
3.1:父节点为黑色则直接添加新节点
-
3.2:父节点为红色则观察叔叔节点颜色
-
3.2.1叔叔节点为红色
-
- 将"父节点"设为黑色,将"叔叔节点"设为黑色
-
- 将"祖父节点"设为红色
-
- 如果"祖父节点"为根节点,则将根节点再次变成黑色
-
-
3.2.1叔叔节点为黑色
-
- 将"父节点"设为黑色
-
- 将"祖父节点"设为红色
-
- 以"祖父节点"为支点进行旋转
-
-
-
Stream-可变参数
可变参数
概述
- 可变参数的意思就是参数的数量可以任意改变
本质
- 就是数组
优势
- 比数组更灵活,可以接受数组实参,也可以接收任意多个零散的实参;
格式
- public 返回值类型 方法名(数据类型… 形参){}
注意事项
- 1:可变参数必须也只能使用在方法的形参列表的位置;
- 2:可变参数必须在参数列表的最右边;
- 3:一个方法中最多只能使用一个可变参数
Collections工具类
概述
Collections工具类,是专门为单列集合提供服务的工具类;
使用方式
都是静态方法,利用类名.方法名即可使用;
常用方法
- addAll(集合容器,元素的可变参数);
- shuffle(list集合);对list集合随机打乱顺序;
- sort(list集合,比较器对象);按比较器的规则对list集合排序;
stream流
概述
- 处理事情的流程;(模型)
作用
- 1:流可以直接操作单列集合或数组;
- 2:如果想操作map集合,需要将map先转成单列集合;
获取流对象的三种方式
- 1:通过单列集合中的默认方法,stream();// 当已经有集合对象时,可以采用这种方式;
- 2:通过Stream接口中的静态方法,of(T… );//当操作数组或零散的数据时,可以使用这种方式;
- 3:数组转成流对象 Arrays.stream(数组);
- 4:如果是map集合,不能直接获取流对象,需要先将双列集合转成单列集合,然后才可以获取流对象;
具体参考代码:
Stream流的获取
单列集合 : 集合对象.stream();
双列集合 : 不能直接获取,需要间接获取
集合对象.keySet().stream();
集合对象.entrySet().stream();
数组 : Arrays.stream(数组名);
同种数据类型的多个数据:
Stream.of(数据1,数据2,数据3......);
注意事项
如果有数组类型的数据转成流对象的时候,**优先考虑使用Arrays.stream(数组名);**因为绝对不会出问题;虽然我们的Stream.of(可变参数)也可以接收数组,但是如果数组是基本数据类型的数组,会把数组当成一个整体添加到流对象中,不安全;
常用方法
-
终结方法
-
特点
- 1:返回值不再是流对象;
- 2:一旦调用后,就不能再使用流中的方法了;
-
分类
-
Count
- 没有参数,直接得到一个long类型的值,表示流对象中的元素个数;
-
forEach
- 遍历流中的每一个元素;有一个Consumer类型的参数;
-
-
-
延迟方法(非终结方法)
-
特点
- 1:返回值依然是流对象;
- 2:调用后,可以继续使用流中的方法,也可以链式调用;
-
分类
-
filter
- 过滤流中的元素,具体的过滤规则,由调用filter方法的人编写lambda决定;
-
skip
- 参数是一个整数,代表跳过流中的前n个元素;
-
limit
- 参数是一个整数,代表保留流中的前n个元素;
-
map
- 映射;(将流中的元素从A类型转成B类型);
-
-
-
静态方法
- concat(流1,流2)
流转集合(收集元素到集合中)
-
使用方法
- collect(参数)
-
参数类型
-
1:转List集合
- 实参为: Collectors.toList() ;这是静态方法
-
2:转Set集合
- 实参为: Collectors.toSet() ;这是静态方法
-
3:转Map集合
- 实参为: Collectors.toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) ;这是静态方法,但是需要传递转key和转vlaue的规则
-
注意事项
- 对于同一个流对象来说,无论调用了延迟方法还是终结方法,那么这个流都无法再次使用了,只能通过流对象的返回值继续操作(相当于流水线中,已经过去的岗位就再也回不去了);
File类
字节流
字节流读数据乱码的原因:
是因为读数据的时候采用的编码方式和当初写数据的人采用的编码不一致引起的
FileOutputStream:
public static void main(String[] args) throws IOException {
//文件存在先删后建 不存在直接创建
FileOutputStream fos = new FileOutputStream("D:\\a.txt");
fos.write(97);
fos.close();
}
public boolean createNewFile(): 创建一个新的空的文件夹(不用)
1.如果文件夹存在,那么创建失败返回false
2.如果文件夹不存在返回true
public boolean mkdir():创建由此File表示的目录,智能创建单个文件夹
public boolean mkdirs():创建由此File表示的目录,多级文件夹。
File f1 = new File("D\\a\\b\\c");
Boolean b = f1.mkdirs();
System.out.println(b);
public boolean delete():删除由此File表示的文件或目录
public static void main(String[] args) {
//删除一个多级文件夹
//delete 只能删除文件和空文件夹
File src = new File("D:\\day10");
deleteDir(src);
}
public static void deleteDir(File src){
//先删除这个文件夹里边所有的东西
//递归调用
//1.进入
File[] files = src.listFiles();
//遍历
for (File file : files){
if (file.isFile()){
//如果是一个文件那么删除
file.delete();
}else{
deleteDir(file);
}
}
src.delete();
}
1.不走回收站
2.如果删除的是文件,那么直接删除,如果是文件,那么能删除空文件夹。
public boolean isDirectory():测试此抽象路径名表示的File是否为目录
public boolean isFile():测试此抽象路径名表示的File是否为文件
public boolean exists():测试此抽象路径名表示的File是否存在
public String getName():返回由此抽象路径名表示的文件或目录的名称
getPath():获取路径
getAbsolutePath():获取绝对路径
public static void main(String[] args) {
//new关键字仅仅创建了一个1.txt,硬盘中有没有不一定
File f1 = new File("D://1.txt");
System.out.println(f1.exists());
//绝对路径就是直接写文件名的路径 相对路径是从盘符开始的路径
File f2 = new File("11.txt");
System.out.println(f2.exists());
System.out.println("isFile"+f1.isFile());
System.out.println("是否存在:"+f1.exists());
System.out.println("文件名:"+f1.getName());
System.out.println("getPath:"+f1.getPath());
System.out.println("getAbsoulet:"+f1.getAbsolutePath());
System.out.println("getPath:"+f2.getPath());
System.out.println("getAbsoulet:"+f2.getAbsolutePath());
}
目录的遍历
public String[] list():
public File[] listFiles():返回此抽象路径表示的目录中的文件和目录的File对象数组
public static void main(String[] args) {
File file = new File("D:\\aaa");
File[] files = file.listFiles();//返回值是一个File类型数组
System.out.println(files.length);
for (File path : files){
System.out.println(path);
}
}
注意事项:
当调用者不存在时,当调用者是一个文件时,当调用者是一个需要权限才能进入的文件夹时,返回null
没有空参构造,需要传递路径,推荐使用绝对路径因为安全
FileInputStream:
public static void main(String[] args) throws IOException {
//如果文件存在,那么不会报错
//如果文件不存在,那么会报错
FileInputStream fis = new FileInputStream("day11\\a.txt");
/*int read = fis.read();*/
int read;
while ((read = fis.read())!=-1){
System.out.println((char)read);
}
//一次读取一个字节,返回值就是本次读到的字节