JAVA高级知识点归纳总结

数组和集合

数组的特点

  • 数组中保存的元素都是有的,可以通过索引快速访问

  • 数组中保存的元素都是同一类型

  • 数组的长度在定义后,无法改变

  • 数组无法获取其中保存的元素实际数量。

集合的特点

  • 能保存一组数据,元素可以有序或无序(存入的顺序和读取的顺序不一致)

  • 集合中保存的元素的数据类型可以不同

  • 集合的容量可变

  • 可以获取集合中保存的元素实际数量

集合家族(集合框架)

Collection接口:

List接口:
ArrayList实现类:有序,可重复,使用数组实现
LinkList实现类:有序可重复,使用链表实现
Set接口:
HashSet:无序不重复,使用HashMap实现
TreeSet实现类:可定义有序或无序,重复或不重复,由compareTo方法的返回值决定

Map接口:

HashMap实现类:使用键值对保存元素,键不重复,值可以重复。使用数组+链表+黑红树实现。

Collection接口

该接口中有两个核心子接口:List和Set。

这两个接口都可以保存一组元素,List接口保存元素有序可重复。Set接口保存元素无序不重复。

Collection接口有一个父接口Iterable,它不是一个集合,而是用于遍历集合的工具接口。包含forEach()和iterator()方法。

常用方法

返回值

作用

add(Object obj)

boolean

将元素添加到集合中

size()

int

获取集合中的元素数量

isEmpty()

boolean

判断集合是否为空

clear()

void

清空集合

contains(Object obj)

boolean

判断集合中是否包含指定元素

remove(Object obj)

boolean

移除集合中的指定元素

toArray()

Object[]

将集合转换为数组

stream()

Stream

获取集合中的流对象,用于遍历集合

iterator()

Iterator

得到集合的迭代器对象,用于遍历集合

List接口(有序可重复)

常用方法

返回值

作用

get(int index)

Object

得到指定索引的元素

set(int index,Object obj)

Object

使用obj替换index上的元素,返回被替换的元素

add(int index,Object obj)

void

将obj添加到index上

remove(int index)

Object

移除指定索引的元素,返回被移除的元素

indexOf(Object obj)

int

得到obj第一次出现的索引

lastIndextOf(Object obj)

int

得到obj最后一次出现的索引

subList(int from,int to)

List

截取[from,to)区间中的元素,返回子集合

List.of(E...element)

List

根据参数创建一个不可变集合,该集合不能对其中的元素进行修改。

ArrayList实现类(掌握)
  • 采用数组实现的集合

  • 可以通过索引访问元素,可以改变集合大小,如果要在其中插入或删除元素时,会影响后续元素

  • 该集合查询效率高,中途添加和删除元素效率低

  • 集合中保存的都是引用类型,如集合中保存123,保存的不是int类型的123,而是Integer类型的123.

构造方法

构造方法

说明

ArrayList()

创建一个Object类型的空数组,再调后续添加方法时,才会初始化数字大小为10.

ArrayList(int initialCapacity)

创建一个指定容量的Object类型数组,如果参数为负数会抛出IllegalArgumentException异常

ArrayList(Collection c)

根据指定集合创建Object类型数组

常用方法

主要以List接口和Collection接口中的方法为主。

LinkedList实现类
  • 采用双向链表实现的集合

  • 集合中保存的每个元素称为节点,除首位节点外,其他节点既保存了自己的数据,还保存了其他前后节点的地址。

  • 如果在双向链表的结构中进行插入和删除节点的操作时,不会影响其他节点现在保存的位置。添加的节点只需记录前后节点的位置接口。

  • 如果要查询某个节点的地址时,需要从头结点或为节点开始搜索目标节点的位置。

  • 双向链表在中间插入和删除数据效率高,随机读取的效率低。

构造方法

LinkedList():创建一个空双向链表

常用方法

主要以List接口和Collection接口中的方法为主。由于还实现了Deque接口,所以还有一些Deque接口中的方法。如操作尾结点的方法。

常用来自于Deque接口中的方法

作用

addFirst(Object obj)

添加obj为头结点

addLast(Object obj)

添加obj为尾结点

getFirst()/Last()

得到头结点,得到尾结点

removeFirst()removeLast()

移除头结点,移除尾结点

ArrayList和LinkedList的区别

  • 这两个类都是List接口的实现类,保存的元素有序可重复,允许保存null。

  • ArrayList采用数组实现,随机读取效率高,插入和删除效率低,适用于查询

  • LinkedList采用双向链表实现,插入和删除效率高,随机读取效率低,适用于频繁更新集合。

Set接口 无序不重复

无序结合,元素不能重复,允许保存null,没有索引

Set接口中的方法都是继承于Collection接口

哈希表是一种数据结构,也称为散列表,能更快速的访问数据。

假设原本的数据为左侧的数据,如要查询10需要遍历数组,效率不高。

通过一个特定的函数"原始值%5",得到一组新数组,让新数据重写对应元素,保存到新数组中,这个新数组称为哈希表。

这时如果要查询10,由于哈希函数是10%5得到0,所以直接查询哈希表中0对应的元素即可。

整个过程中,这个函数称为哈希函数,得到的新数组称为哈希码,对应关系为哈希映射。

这个哈希函数,有一定几率让多个原始值得到相同的哈希码,这种情况称为哈希冲突(哈希码相同,实际只不同)。

哈希码的特点
  • 如果两个对象的hashcode不同,这两个对象一定不同

  • 如果两个对象的hashcode相同,这两个对象不一定相同。

hashcode相同,对象不同:哈希冲突

"通话"和"重地"两个字符串的hashcode相同,但是两个不同的对象

HashSet实现类
  • 采用哈希表实现

  • 元素不能重复,无序保存,允许保存一个null

  • 本质是HashMap对象

  • 使用HashSet集合时,通常要重写实体类中的equals和hashcode方法

构造方法

HashSet() 创建一个空集合,实际是创建一个HashMap对象

常用方法

HashSet中没有定义属于自定的方法,都是父接口Set和Collection中的方法

HashSet添加数据的原理

如果添加的两个元素的equals方法结果为true且hashcode相同时,视为同一个对象,不能添加

每次向集合添加元素时,先判断该元素的hashcode是否存在

  • 如果不存在,视为不同对象,直接添加

  • 如果存在,在判断equals方法的结果

如果为true,视为同一个对象,不能添加

如果为false,视为不同对象,可以添加

不能添加的条件是hashcode相同且equals的结果为true

可以只判断equals结果,但效率不高

如果只判断hashcode是否相同,效率高,但可能出现哈希冲突

equals和hashcode的关系

  • 如果两个对象的equals方法结果为true,在没有重写equals方法的前提下,hashcode相同吗?

如果没有重写equals方法,默认使用Object中的方法,使用==判断,如果结果为true,说明是同一个地址,同一个对象,hashcode一定相同

  • 如果两个对象的hashcode不同,在没有重写equals方法的前提下,equals的结果为:

hashcode不同,说明不是同一个对象,没有重写equals说明使用Object方法,==判断,结果为false

  • 如果两个对象的hashcode相同,equals方法的比较结果:可能为true,可能为false

String str1="hello";
String str2="hello";
//str1和str2使用同一个地址,hashcode相同,equals结果为true
String str3="通话";
String str4="重地";
//str3和str4不是同一个地址,但hashcode相同,是哈希冲突,结果为false

HashSet的应用

如果要保存的对象保证不重复,且无关顺序,可以使用HashSet,重写要保存的元素的hashcode方法。

Student类,保证添加对象时,不重复

public class StudentManager{
private HashSet<Student>hs=new HashSet<>();
//添加时,如果对象的属性都一致,视为同一个对象,不能重复添加
public void addStudent(Student student){
  hs.add(student);
    }
}
TreeSet实现类
  • 特殊的Set实现类,数据可以有序保存,可以重复,不能添加null

  • 曹勇红黑树(自平衡二叉树)实现的集合

1.二叉树表示某个节点最多两个子节点

2.有个节点右侧值大于左侧值节点

3.红黑树会经过"变色"和旋转大道二叉树的平衡

  • 只能添加同一种类型的对象且该对象实现了Comparable接口

1.每次调用add方法添加元素时,会自动调用Comparable接口中的方法compareTo()方法

2.实现Comparable接口后必须要重写compareTo()方法,用于决定新添加的元素放在旧元素之前或之后。

  • compareTo()方法的返回值决定了能否添加新元素和新元素的位置。

1.如果返回0,视为每次添加都是同一个元素,不能重复添加。

2.如果返回正数,将新元素添加到现有元素之后

3.如果返回负数,将新元素添加到现有元素之前。

  • 添加的元素可以自动排序

构造方法

TreeSet() 创建一个空集合

常用方法

能使用Set和Collection接口中的方法,还定义了一些属于它的方法

独有方法

作用

first()last()

得到集合中的第一个元素,得到集合中的最后一个元素

ceiling(Objcet obj)

得到集合中比参数大的元素中的最小元素

floor(Object obj)

得到集合中比参数小的元素中的最大元素

TreeSet的应用

如果要保存的元素需要对其根据某个属性排序,使用该集合

如果在集合中保存整数,即Integer对象,Integer类已经实现了Comparable接口

如果要保存自定义的元素,必须要实现Comparable接口,重写compareTo方法,自定义排序规则

Main类

Map接口

Map接口称为映射,该集合中保存的数据是以键值对的形式保存,保存的键与值的映射关系。

键称为Key 值称为Value,键不能重复,允许出现一个null作为键,值没有限制。

键和值都必须是引用类型。

yyds---yyds "yyds"是键key 永远单身是值value

常用方法

作用

size()

得到键值对的数量

isEmpty()

判断是否为空集合

clear()

清空所有键值对

put(Object key,Object value)

添加一组键值对

get(Object key)

根据键值对得到对应的值

containsKey(Object key)

判断是否存在某个值

containsValue(Object value)

判断是否存在某个值

keyset()

得到键的集合

values()

得到值的集合

entrySet()

得到键值对的集合

remove(Object key)

删除指定的键值对

HashMap实现类

构造方法

HashMap() 创建一个大小为16,加载因子为0.75的空集合

常用方法

使用Map接口中的方法

HashMap采用"数组+链表+红黑树"实现

  • 当没有出现哈希冲突时,元素保存在数组中

  • 如果出现哈希冲突,在对应的位置上创建链表,元素保存到链表中

  • 如果链表的长度大于8,将链表转换为红黑树

遍历集合的方式

遍历List集合

普通for循环
for(int i=0;i<集合.size();i++){
元素 变量=集合.get(i)
}
增强for循环
for(数据类型 变量名:集合){
元素 变量=集合.get(i)
}
forEach()方法

使用该方法遍历集合时,不要使用add或remove操作,遍历会抛出异常

集合.forEach(obj->{
元素 变量=集合.get(i);
});
迭代器
//collection接口有一个父接口Iterable,其中有一个iterator方法用获取迭代器对象遍历集合
//所有Collection的子实现类都能调用该方法
Iterator it=Collection集合.iterator();
//hasNext()判断是否还有下一个元素
while(it.hasNext()){
//next()方法读取钙元素
元素 变量=it.next();
}

遍历Set集合

普通for循环无法遍历Set集合,因为元素没有索引

增强for循环

for(数据类型 变量名:集合){
元素 变量=集合.get(i);
}

forEach()方法

集合.forEach(obj->{
元素 变量=集合.get(i);
});

迭代器

//Collection接口有一个父接口Iterable,其中有一个iterator方法用于获取迭代器对象遍历集合
//所有Collection的子实现类都能调用该方法
Iterator it = Collection集合.iterator();
//hasNext()判断是否还有下一个元素
while(it.hasNext()){
    //next()方法读取该元素
    元素 变量 = it.next();
}
遍历HashMap集合
Set keySet=集合.keySets();
for(object key :keySet){
Object value=集合.get(key);
}

泛型

一种规范,常用于限制集合中的元素类型。省去遍历集合时转换Object对象的过程

//默认可以保存任意类型的元素,即Object类型
List list=new ArrayList();
list.add(123);
list.add("hello");
//遍历时只能使用Object类型获取
for(Object obj:list){
}

使用泛型

在定义集合时,在集合类或接口后协商<引用数据类型>

集合类或接口<引用数据类型>集合遍历名=new 集合实现类();

//定义只能泡村整数的集合,要是有整数的包装类型
List<Integer>list=new ArrayList();
list.add(123);
//不能添加非整数
//list.add("hello");

Collections集合工具类

  • Collection是集合的根接口,定义了操作集合中元素的方法

  • Collections是集合的工具类,定义了操作集合中元素的静态方法。

Collections中的静态方法

说明

Collections.shuffle(List list)

打乱集合中元素的顺序

Collections.sort(List list)

对集合中的元素进行排序,元素必须实现Comparable接口

Collections.swap(List list,int a,int b)

将集合中索引a和b的元素交换位置

Collections.reverse(List list)

反转集合中的元素

Collections.max(Collection c)

得到集合中元素的最大值,元素必须实现Comparable接口

Collections.rotate(List list,int distance)

将集合中最后distance个元素放在集合最前

Collections.fill(List list,Object obj)

使用obj填充集合

Arrays数组工具类

包含一些操作数组的静态方法

常用静态方法

说明

Arrays.sort()

对数组中的元素升序排列

Arrays.asList(T...obj)

将可变参数转换为ArrayList集合

集合与数组之间的转化

数组转换为集合

//调用Arrays工具类的asList(1,2,3,4,5)或asList(数组)
ArrayList<Integer>list=Arrays.asList(1,2,3,4,5);

集合转换为数组

ArrayList list=new ArrayList();
list.add("sdf");
list.add(123);
list.add(null);
//调用集合的toArray()方法
Object[] objs=list.toArray();

无论数组转集合还是集合转数组,都可以进行遍历

如果集合转换为数组,遍历集合,通过索引赋值

如果数组转换为集合,遍历数组,通过add()添加元素

文件类File

Java中的File类,表示本地硬盘中的文件file或文件夹directory的一个类

通过这个类创建对象,可以读取文件信息或操作对应文件。

构造方法

常用构造方法

说明

File(String pathName)

根据文件的完整路径创建File对象

File(String parent,String child)

根据文件的父目录的路径和自身的名称创建File对象

File(File parent,String child)

根据文件的父目录对应的File对象和自身的名称创建File对象

File file1 = new File("C:\\Users\\Administrator\\Desktop\\230202.txt");

File file2 = new File("C:\\Users\\Administrator\\Desktop", "230202.txt");

File parent = new File("C:\\Users\\Administrator\\Desktop");

常用方法

常用方法

作用

exists()

判断文件是否存在

isFile()

判断是否为文件

isDirectory()

判断是否为文件夹

getName()

获取文件名

getPath()

获取文件相对路径

getAbsolutePath()

获取文件绝对路径

length()

获取文件字节大小

delete()

删除文件或空文件夹

mkdir()

创建文件夹

listFiles()

得到文件夹中的第一层子文件对象的数据,返回File[]

//递归调用
public static int fun(int n){
if(n>2){
return fun(n-1)+fun(n-2);
}
return 1;
}
递归遍历文件夹

IO

I:input输入

O:output输出

流Stream

流表示计算机硬盘与内存之间传输数据的通道

内存中的数据存入到硬盘中,称为写write,也称为输出Output

硬盘中的数据存入到内存中,也成为了读read,也称为输入Input

流的分类

字节输入流InputStream

FileInputStream ObjectInputStream

字节输出流OutputStream

FileOutputStream ObjectOutputStream

字符输入流Reader

FileReader、BufferedReader、InputStreamReader

字符输出流Writer

FileWriter、BufferedWriter、OutputStreamWriter

按方向分类

  • 输入流:InputStream Reader

读取硬盘中的数据到程序中

  • 输出流:OutputStream Writer

将程序中的数据写到硬盘中

按数据传输类型分类:

  • 字节流:InputStream OutputStream

读写非文本类型文件,如图片,多媒体文件

  • 字符流:Reader,Writer

读写纯文本文件,如txt,md等

如要将硬盘中的某个txt文件中的内容读取到程序中,使用Reader

如要将硬盘中的某个图片文件中的内容读取到程序中,使用InputStream

如要将程序中的文本写入到硬盘中,保存为txt文件时,使用Writer

如果要将程序中的数据写入到硬盘中,保存为非文本文件时,使用OutputStream

流的四个父类的特点

  • 这四个父类都是在java.io包下,都是抽象类,不能直接创建其对象,使用其子类对象

  • 这四个类都有close()方法,用于关闭流对象,释放资源。

  • 输入流(InputStream和Reader)都有read()方法,用于读取数据,输出流(OutputStream和Writer)都有write()方法

  • 输出流(OutputStream和Writer)都有flush()方法,用于将流中的数据冲刷到硬盘中

在使用输出流对象时,一定要将调用flush()或close()方法后,才能真正将数据写入到硬盘中

  • 所有流中,以Stream结尾,都是字节流,数据以字节传输,以Reader或Writer结尾,都是字符流,数据以字符传输。

  • 读取硬盘中的数据时,读取的文件必须存在,写入数据到硬盘中时,写入的文件可以不存在,但父目录必须存在。

FileInputStream文件字节输入流

以字节的形式读取文件

构造方法

常用构造方法

作用

FileInputStream(String filePath)

根据文件完整路径创建流对象

FileInputStream(File file)

根据文件对象创建流对象

常用方法

常用方法

作用

read()

读取一个字节,返回读取到的字节

read(byte[] bytes)

读取指定数组大小的字节,返回读取到的字节数量

read(byte[]buyes,int off,int len)

读取指定数组大小的字节,从off索引开始读取len个字节,返回读取到的字节数量

available()

文件可读取的最大字节数量

close()

关闭流对象

使用FileInputStream和FileOutputStream读写时的注意事项

在通过FileInputStream对象使用read(byte[] bytes)方法时,每次读取指定数组的字节,将读取到的字节保存在字节数组中。

该方法的返回值是读取到的字节数量,如果最后一次读取的字节数量不足字节数组的大小时,只会将读取到的内容覆盖数组中最前的几个元素。所以最后一次读取时,读取的内容多于实际内容。

在通过FileOutputStream对象使用write(byte[] bytes),会将字节数组中的所有内容写入到输出流中,在最后一次写入时,会写入多余的内容。所以在写入时,使用write(byte[] bytes,int off,int len)方法,表示将字节数组中的内容,从off开始写入len个

单文件复制

//使用FileInputStream读取字节的同时使用FileOutputStream写入字节,实现单文件复制
File source = new File("d:\\xxx.txt");
//读取
FileInputStream fis = new FileInputStream(source);
//写入到目标文件中
FileOutputStream fos = new FileOutputStream("f:\\copy.txt");
//定义字节数组,大小为8MB
byte[]bytes=new byte[1024*1024*8];
//读取之ID你数组大小的字节,返回读取到的字节数量
int count=fis.read(bytes);
while (count>0) {
            //写入指定数组的字节
            //fos.write(int b);写入一个字节
            //fos.write(byte[] bytes);写入一个数组的字节
            fos.write(bytes,0,count);//写入一个数组的字节,从0开始写入读取到的数量的字节
            count = fis.read(bytes);
       }
        fis.close();
        fos.close();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值