文章目录
四.基础API
1.Object
1.是所有类的超类,Java中的类都直接或者间接的继承了Object
2. 如果一个类没有明确指定父类,那么默认继承Object
3. Object处于java.lang包之下,不需要导包可以直接使用
4. toString()–我们日常使用最频繁的打印语句底层就调用了这个方法
如果没有重写这个方法,使用的是Object的默认实现,打印的是对象的地址值
如果重写以后,以重写的逻辑为准,比如String打印的是串的具体内容,比如ArrayList,打印的是[集合元素]
5. hashCode()–用于返回对象对应的哈希码值
如果是一个对象多次调用这个方法,返回的是同一个哈希码值
如果是不同的对象调用这个方法,应该返回的是不同的哈希码值
6. equals()–用于比较当前对象与参数对象是否相等
重写之前的默认实现比较的是两个对象的地址值
重写之后取决于重写的逻辑,比如String比较的是两个串的具体内容,比如自定义对象比较的是类型+属性值
7. equals()与hashCode()应该保持一致【要重写都重写】
解释:equals()底层默认实现比较的是==比较,地址值,重写后我们一般比较的是对象的类型+属性值
hashCode()不同的对象生成的哈希码值不同,那么与equals()的逻辑不匹配,所以也应该重写
重写后,是根据对象的类型与属性值来生成哈希码值,这样二者就一致了
package cn.tedu.api;
import java.util.Objects;
/*本类用于顶级父类Object的入门案例
* 1.查API手册
* 2.连点两下shift打开IDEA的搜索,注意勾选"include non-project item",再搜Object
* 3.在拓展库External Libraries
* 4.
* */
public class TestObject {
public static void main(String[] args) {
Students s =new Students();
Students s1 =new Students("海绵宝宝",3);
Students s2 =new Students("海绵宝宝",3);
//测试hashCode
/*本方法的作用是返回对应对象的的int类型的哈希码值
* 本方法力求不同的对象返回的哈希码值不同
* 这样我们就可以根据哈希码值区分不同的对象*/
System.out.println(s.hashCode());
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
//测试toString
/*Object中toString()的默认实现:对象的地址值[对象类型@十六进制的哈希码值]
* 子类重写了toString()以后,打印的是:对象的类型+属性+属性值*/
System.out.println(s);
System.out.println(s1);
//System.out.println(1==1);
/*Object中equals()*的迷人实现使用的是==比较
* ==比较的是左右两边的值,如果是基本类型,比较的就是字面值,比如1和1,3.4和3.4
* 如果是引用类型,比较的是引用类型变量保存的地址值
* 子类重写了equals()与hashCode()以后,比较的就是对象的类型+属性+属性值*/
System.out.println(s1.equals(s2));//false
}
}
class Students{
String name;//姓名
int age;//年龄
public Students(){
System.out.println("无参构造");
}
public Students(String name, int age) {
this.name = name;
this.age = age;
System.out.println("全参构造");
}
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/*equals()和hashcode()逻辑要保持一致,要重写都重写,要不重写,都不重写
* Object默认实现:hashcode()的哈希码值根据地址值生成
* equals()底层使用==比较两个对象的地址值
* student类重写后:hashcode()的哈希码值根据重写传入的对象的属性生成
* equals()比较两个对象的类型+所有属性与属性值*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Students students = (Students) o;
return age == students.age && Objects.equals(name, students.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
2.String
1.String底层维护的是一个char[],而且String不可变,因为源码中的数组被final修饰了
创建方式:
2.char[] vlaues = {‘a’,‘b’,‘c’}; String s = new String(values);
String s = “abc”;有高效的效果,因为串存在堆中的常量池,第二次使用时就不再新建了
3.常用方法:
int hashCode() 返回此字符串的哈希码。
boolean equals(Object anObject) 将此字符串与指定的对象比较,比较的是重写后的串的具体内容
String toString() 返回此对象本身(它已经是一个字符串!)。
int length() 返回此字符串的长度。
String toUpperCase() 所有字符都转换为大写。
String toLowerCase() 所有字符都转换为小写
boolean startsWith(String prefix) 测试此字符串是否以指定的元素开头。
boolean endsWith(String suffix) 测试此字符串是否以指定的字符串结束。
char charAt(int index) 返回指定索引/下标处的 char 值/字符
int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。
int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。
String concat(String str) 将指定字符串连接/拼接到此字符串的结尾,注意:不会改变原串
String[] split(String regex) 根据给定元素来分隔此字符串。
String trim() 返回去除首尾空格的字符串
byte[] getBytes() 把字符串存储到一个新的 byte 数组中
String substring(int beginIndex) 返回一个新子串,从指定下标处开始,包含指定下标
String substring(int beginIndex, int endIndex) 返回一个新子串,从执定下标开始,到结束下标为止,但不包含结束下标
static String valueOf(int i) 把int转成String
package cn.tedu.api;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Locale;
//本类用来测试String类的常用方法
public class TestString2 {
public static void main(String[] args) {
char [] vale1 ={'a','b','c'};
String s1 = new String(vale1);
String s2 ="abc";
/*String重写了hashcode(),是根据字符串的具体内容生成哈希码值,而不是根据地址值生成
* 所以虽然s1与s2的地址值不同,但是它们的哈希码值一样*/
System.out.println(s1.equals(s2));//true
System.out.println(s1.hashCode());//96354
System.out.println(s2.hashCode());//96354
/*String也重写了Object中的toString(),打印的是字符串的具体内容*/
System.out.println(s1);//abc
System.out.println(s1.length());//3,查看当前字符串的长度
System.out.println(s1.toUpperCase());//ABC--本字符串转成全大写
System.out.println(s1.toLowerCase());//abc--本字符串转成全小写
System.out.println(s1.startsWith("a"));//true--判断本字符串是否以"a"开头
System.out.println(s1.endsWith("a"));//false--判断字符串是否以"a"结尾
System.out.println(s1.charAt(0));//a--根据下标获取本字符串中对应位置的元素
String s3 = "abcbdbba";
System.out.println(s3.indexOf("b"));//1--返回指定字符第一次出现的下标
System.out.println(s3.lastIndexOf("b"));//6--返回指定元素最后一次出现的下标
System.out.println(s2.concat("cxy"));//abccxy--将指定字符串拼接到本字符串的结尾
System.out.println(s2);//abc--说明上面的拼接是临时的,不会改变原有s2的内容
String s4 =s2.concat("aaa");//如果想要多长使用拼接后的结果,需要定义一个字符串保存结果
System.out.println(s4);//abcaaa
String s5 = "afbfcfdfe";
//返回值类型是String[],所以需要Arrays.toString()打印
//以指定字符作为分隔符,分割当前的字符串
String[] a = s5.split("f");
System.out.println(Arrays.toString(a));//[a, b, c, d, e]
for (int i = 0; i <a.length; i++) {
System.out.println(a[i]);
}
String s6 = " hh hhh ";
System.out.println(s6.trim());//hh hhh--去除字符串首尾两端的空格
String s7 = "abcdefgh";
System.out.println(s7.substring(3));//defgh--从指定下标处开始截取子串[3,结束]
System.out.println(s7.substring(3,6));//def--从指定下标处开始截取子串[3,6)含头不含尾
System.out.println(20+10);//30--int+int
System.out.println("20"+10);//2010--String+int拼接效果
System.out.println(String.valueOf(10));
System.out.println(String.valueOf(80)+10);//8010--将int类型的80转成String类型
byte[] bs = s7.getBytes();//将指定字符串转成byte
System.out.println(Arrays.toString(bs));//[97, 98, 99, 100, 101, 102, 103, 104]
}
}
3.StringBuilder与StringBuffer
1.String的:
1.特点:
创建之后长度内容是不可变的,每次拼接字符串,都会产生新的对象
2.优缺点:
优点:String类提供了丰富的关于操作字符串的方法,比如:拼接、获取对应下标处的字符、截取子串等等
缺点:在进行字符串拼接+=的时候,效率比较低
3.String转StringBuilder:
String s = “abc”; StringBuilder sb = new StringBuilder(s);
2.StringBuilder的:
1.特点:
StringBuilder是一个长度可变的字符串序列,在创建的时候,会有一个长度为16的默认空间
当拼接字符串的时候,是在原对象的基础之上进行拼接,如果长度不够就扩容
所以StringBuilder在创建之后,对应的操作一直是用一个对象
2. 创建方式:
StringBuilder sb = new StringBuilder();//创建一个长度为16的StringBuilder对象
StringBuilder sb = new StringBuilder(“abc”);//以指定字符串内容为“abc”的方式创建一个StringBuilder对象
3. 优缺点:
优点:在拼接的时候,不会产生新的对象,就避免了因为拼接频繁生成对象的问题,提高了程序的效率,使用的是append()
缺点:对于字符串的操作,不太方便
4. StringBuilder转String:
StringBuilder sb = new StringBuilder();
sb.append(“abc”);
String s = sb.toString();
总结一句话,拼接多用StringBuilder,用完转回String用String丰富的方法
4.包装类
- 基本类型只存值,也没有丰富的功能
所以包装类型是对基本类型做了包装,并提供了很多方便的方法,所以包装类的对象是引用类型的对象 - 创建方式:
Integer i1 = Integer.valueOf();数据只要在-128~127有一个高效的效果
Integer i2 = new Integer(4);没有高效的效果,只是创建了一个包装类的对象
package cn.tedu.api;
/*本类用于测试包装类*/
public class TestNumber {
static Integer i0;
public static void main(String[] args) {
//包装类型也是引用类型,默认值是null
System.out.println(i0);//null
//创建int类型对应得包装类型Integer的对象
Integer i1 = new Integer(5);
Integer i11 = new Integer(5);
System.out.println(i1 == i11);//false
/*Integer有一个高效的效果,如果使用valueOf()的创建方式
* 并且数据在-128~127范围内,相同的数据只会存一次
* 后续再存都是使用之前存过的数据*/
Integer i2 = Integer.valueOf(127);
Integer i3 = Integer.valueOf(127);
System.out.println(i2 == i3);//true
//满足高效效果的3个条件: Integer valueOf -128~127
Integer i4 = Integer.valueOf(300);
Integer i5 = Integer.valueOf(300);
System.out.println(i4 == i5);//false
Double d1 = new Double(3.14);
Double d2 = new Double(3.14);
System.out.println(d1 == d2);//false
Double d3 = Double.valueOf(3.14);
Double d33 = Double.valueOf(3.14);
System.out.println(d1 == d3);//false
System.out.println(d3 == d33);//false
//parseInt():将String类型的数据转成int的类型
System.out.println(Integer.parseInt("800")+8);//808
//parseDouble():将String类型的数据转成double类型
System.out.println(Double.parseDouble("2.2")+1.1);//3.3
}
}
5.自动装箱与自动拆箱
1.自动装箱:
编译器会自动把基本类型int5,包装成包装类型Integer
然后交给Integer类型的引用类型变量i3来保存
自动装底层发生的代码:Integer.valueOf(5)
valueOf()的方向:int–>Integer
2. 自动拆箱:
编译器会自动把包装类型的i1拆掉”箱子“,变回基本类型的数据127
然后交给基本类型int的变量i4来保存
自动拆箱底层发生的代码:i1.intValue();
intValue()的方向:Integer-> int
五.高级API
1.IO流
1.学习方式:学习抽象父级的公共方法 学习子类流对象的创建方式
2. 流的分类
根据方向:输入流 输出流
根据操作单位:字节流 字符流
字节输入流InputStream:
InputStream–抽象父类–不能实例化
FileInputStream–文件字节输入流-FIS
BufferedInputStream–高效字节输入流-BIS
FIS in = new FIS(new File(路径));
FIS in = new FIS(路径);
BIS in = new BIS( new FIS(new File(路径)));
BIS in = new BIS(new FIS(路径));
package cn.tedu.file;
import java.io.*;
//本类用于测试字节输入流
public class TestIn {
public static void main(String[] args) {
//method1();//用于测试普通字节输入流FIS
method2();//用于测试高效字节输入流BufferedInputStream
}
private static void method2() {
InputStream in = null;
try {
//1.创建流对象
in = new BufferedInputStream(new FileInputStream("E:\\ready\\1.txt"));
//2.使用流对象
int b;
while((b = in.read()) != -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void method1() {
/*定义一个在本方法中都生效的局部变量,注意手动赋值为null*/
InputStream in = null;
try {
/*1.创建流对象*/
//InputStream in = new FileInputStream(new File("E:\\ready\\1.txt"));//不常用
in = new FileInputStream("E:\\ready\\1.txt");//常用此方式
/*2.使用流对象
* 定义变量来保存*/
int b;
while ((b = in.read()) != -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
}finally {//最终的,局部代码块
/*3.关流*/
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节输出流OutputStream:
OutputStream–抽象父类,不能实例化`
FileOutputStream--文件字节输出流--FOS
BufferedOutputStream–高效字节输出流-BOS`
FOS out = new FOS(new File(路径));
FOS out = new FOS(路径);
BOS out = new BOS(new FOS(new File(路径)));
BOS out = new BOS(new FOS(路径));
字符输入流Reader:
Reader--抽象父类--不能实例化
FileReader--文件字符输入流-FR
BufferedReader--高效字符输入流-BR
package cn.tedu.file;
import java.io.*;
//本类用于测试输出流
public class TestOut {
public static void main(String[] args) {
//method1();//普通字节输出流
method2();//高效字节输出流
}
private static void method2() {
BufferedOutputStream out = null;
try{
//out = new BufferedOutputStream(new FileOutputStream(new File("E:\\ready\\1.txt")));
out = new BufferedOutputStream(new FileOutputStream(new File("E:\\ready\\1.txt"),true));//追加输出
//out = new BufferedOutputStream(new FileOutputStream("E:\\ready\\1.txt"));
//,4out = new BufferedOutputStream(new FileOutputStream("E:\\ready\\1.txt",true));//追加输出
out.write(99);
out.write(99);
out.write(99);
out.write(99);
}catch(Exception e){
e.printStackTrace();
}finally{
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void method1() {
FileOutputStream fos = null;
try {
//1.创建流对象
//OutputStream fos = new FileOutputStream(new File("E:\\ready\\1.txt"));//覆盖输出
//fos = new FileOutputStream("E:\\ready\\1.txt");//覆盖输出
fos = new FileOutputStream(new File("E:\\ready\\1.txt"),true);//追加输出
fos = new FileOutputStream("E:\\ready\\1.txt",true);//追加输出
//2.使用流对象
fos.write(97);
fos.write(97);
fos.write(97);
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FR in = new FR(new File(路径));
FR in = new FR(路径);
BR in = new BR(new FR(new File(路径)))
BR in = new BR(new FR(路径));
字符输出流Writer:
Writer--抽象父类,不能实例化
FileWriter--文件字符输出流--FW
BufferedWriter–高效字符输出流–BW`
package cn.tedu.file;
import java.io.*;
//本类用作测试字符流的读取
public class TestIn2 {
public static void main(String[] args) {
//method1();
method2();
}
/*第二种方法(高效)*/
private static void method2() {
Reader in1 = null;
try {
//1.创建流对象
//in1 = new FileReader(new File("E:\\ready\\1.txt"));
in1 = new BufferedReader(new FileReader("E:\\ready\\1.txt"));
//2.使用流对象
int b;
while((b = in1.read()) != -1){
System.out.println(b);
}
//while(in1.read()!= -1){
// System.out.println(in1.read());
//}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
try {
in1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*第一种方法(普通)*/
private static void method1() {
Reader in = null;
try {
//1.创建流对象
//in = new FileReader(new File("E:\\ready\\1.txt"));
in = new FileReader("E:\\ready\\1.txt");
//2.使用流对象
int b;
while( (b =in.read())!= -1){
System.out.println(b);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FW out = new FW(File/File,append/String pathname/String pathname,append);
BW out = new BW(Writer--所以传的是子类FW(上面那4种));
注意:这里的append参数表示流向文件输出数据的时候是追加还是覆盖,如果不写,默认false是覆盖,如果改为true,表示追加
3.序列化与反序列化
序列化与反序列化的作用就是对象的保存与传输
4.序列化:把内存中的对象通过序列化流输出到磁盘中(比如文件里),使用的流是ObjectOutputStream【把数据写出到文件】
作用:
1.保证数据按照正确的格式输出!!
2.在多线程条件中,共享数据必须序列化
5.反序列化:通过反序列化流将磁盘中的数据恢复成对象,使用的流是ObjectInputStream【把之前写到文件里的数据读到程序中】
注意1:一个类的对象如果想被序列化,那么这个类必须实现可序列化接口
实现这个接口的目的是相当于给这个类做了一个标记,标记可以序列化
注意2:序列化时会自动生成一个UID,表示当前序列化输出的对象的版本信息
反序列化时会拿着当前的UID与之前序列化输出的UID做比较,一致,反序列化成功,不一致,报错
注意3: 所以,标准操作是一次序列化对应一次反序列化
如果目标对象所在的类没有做任何修改,一次序列化也可以对应多次反序列化(根本原因是UID没变)
2.集合
1.泛型
泛型通常与集合一起使用,用来约束集合中元素的类型
泛型< type >必须写引用类型而不是基本类型
泛型方法 public static == < E > == void get(E[] e){},两处位置都出现了泛型,缺一不可
2. 集合被称作Collection,是一个可以存放多个数据的容器,而且集合中提供了丰富的方法来操作集合中的元素
是集合层次的根接口,学习抽象父级的公共方法
3. Collection集合方法总结
单个集合的操作:
boolean add(E e) 将指定元素添加到集合中
void clear() 清空集合
boolean contains(Object o) 判断本集合是否包含指定的元素
boolean equals(Object o) 比较集合对象与参数对象o是否相等
int hashCode() 返回本集合的哈希码值
boolean isEmpty() 判断本集合是否为空
boolean remove(Object o) 从本集合中移除指定元素o
int size() 返回本集合中元素的个数
Object[] toArray() 将本集合转为数组
集合间的操作:
boolean addAll(Collection<> c) 将c集合中的所有元素添加到本集合中
boolean containsAll(Collection<> c) 判断本集合是否包含c集合的所有元素
boolean removeAll(Collection<> c) 移除本集合中属于参数集合c的所有元素
boolean retainAll(Collection<> c) 保留本集合与参数集合c的公共元素
集合的迭代:
Iterator iterator() 返回本集合的迭代器
4.List接口的特点
4.1List集合是有下标的
4.2List集合是有顺序的
4.3List集合可以存放重复的数据
单个集合的操作:
void add(int index, E element) 在集合的指定下标index处插入指定元素element
E get(int index) 返回本集合中指定下标index处的元素
E remove(int index) 移除本集合中指定下标index处的元素
E set(int index, E element) 用参数元素element替换集合中指定下标index处的元素
int indexOf(Object o) 判断指定元素o在本集合中第一次出现的下标,如果不存在,返回-1
int lastIndexOf(Object o) 判断指定元素o在本集合中最后一次出现的下标,如果不存在,返回-1
List subList(int fromIndex, int toIndex) 截取子集合,包含formidex处的元素,不包含toIndex处的元素
集合间的操作与集合的迭代
boolean addAll(int index, Collection<> c) 将参数集合c中的所有元素,插入到本集合中指定的下标index处
ListIterator listIterator() 返回此列表元素的迭代器,这个是List自己的,不太常用,可以逆序迭代
5.List接口的两个常用实现类
ArrayList的特点:
1)底层的数据结构是数组,内存空间是连续的
2)元素有下标,通常可以根据下标进行操作
3)增删操作比较慢,查询操作比较快【数据量大时】
package cn.tedu.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
//本类用于测试ArrayList的相关方法
public class TestArrayList {
public static void main(String[] args) {
//创建对应集合的对象
/*底层会自动帮我们创建数组来保存对应,并且数组的初始容量是10*/
ArrayList<Integer> list = new ArrayList<>();
//向集合添加元素
list.add(100);
list.add(200);
list.add(300);
list.add(400);
list.add(400);
list.add(300);
System.out.println(list);
/*测试常用方法*/
//list.clear();//清空集合
//System.out.println(list);//[]
/*是否包含指定元素100---不包含(这个是String不是integer)*/
System.out.println(list.contains("100"));//false
System.out.println(list.get(0));//100,根据下标获取对应位置的元素
System.out.println(list.indexOf(400));//3,元素300第一次出现的下标
System.out.println(list.lastIndexOf(400));//4,元素300最后一次出现的下标
/*代会报错,数组下标越界:index:300 sinze 6
主要是因为list中有两个重载的remove(),如果传入的是300
* 会直接把这个300看作是int类型的index索引,所以如果想知道元素来删除数据
* 需要把int类型的300手动装箱成integer类型的300元素*/
//System.out.println(list.remove(300));//报错
System.out.println(list);
System.out.println(list.remove(Integer.valueOf(300)));
System.out.println(list);
System.out.println(list.remove(2));
System.out.println(list);
System.out.println(list.set(2,777));//修改指定位置处的元素777
System.out.println(list);
System.out.println(list.size());//4,获取集合中的元素个数
ArrayList<Integer>list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
System.out.println(list2);
list.addAll(list2);//将list2集合的元素添加到list集合中
System.out.println(list);
list.addAll(0,list2);//将list2集合中的所有元素从list集合的0号位置开始添加
System.out.println(list);
list.removeAll(list2);//删除list集合中所包含属于list2的元素
System.out.println(list);
System.out.println(list.contains(list2));//判断list集合中是否包含list2的所有元素
list.add(1);
System.out.println(list.containsAll(list2));
System.out.println(list.containsAll(list2));//取交集,保留list中属于list2的元素
//测试集合的迭代
/*for循环
* 高效for循环
* iterator
* listIterator*/
//方式1:因为list集合有下标,所有可以根据下标进行遍历
//从哪开始0 到哪结束list.size()-1 如何变化
for (int i = 0; i <=list.size()-1; i++) {
System.out.println(list.get(i));
}
System.out.println("..........");
//方法2:因为普通for循环遍历效果低,语法赋复杂,所有使用高效for循环
//格式:for(每轮遍历到的元素的类型 元素名 : 要遍历的元素){循环体}
for (Integer aaa : list) {
System.out.println(aaa);
}
System.out.println("..........");
//方式3:从符接口collection中继承过来的迭代器
//获取要迭代集合对应得迭代器,通过迭代判断是否有下一个元素可迭代,通过迭代器获取本轮迭代到的元素
Iterator<Integer> t = list.iterator();//通过迭代器判断是否有下一个元素可以迭代
while(t.hasNext()){
//通过迭代器获取本轮迭代到的元素
System.out.println(t.next());
}
System.out.println("..........");
/*方式4:ListIterator属于List接口独有的迭代器
Interator<E>--父接口--hasNext(),next()
ListInterator<E>--子接口--可以使用父接口的功能,除了父接口的功能之外,还有自己特有的功能
比如逆序遍历,添加元素等,但注意,很少用
public interface ListInterator<E> extends Iterator<E>
* */
ListIterator<Integer> it = list.listIterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
LinkedList的特点:
1)底层的数据结构是链表,内存空间是不连续的
2)元素有下标,但是通常首尾节点操作比较多
3)增删操作比较快,查询操作比较慢【数据量大时】
注意:LinkedList查询慢也不是都慢,首尾操作还是比较快的
package cn.tedu.Collection;
import java.util.LinkedList;
//本类用于LinkedList的相关测试
public class TestLinkedList {
public static void main(String[] args) {
//1.创建集合对象
LinkedList<String> list = new LinkedList<>();
//2.添加数据
list.add("孙悟空");
list.add("猪八戒");
list.add("唐三藏");
list.add("沙师弟");
list.add("白龙马");
System.out.println(list);
//3.
//4.测试LinkedList
list.addFirst("蜘蛛精");//添加首元素
System.out.println(list);//[蜘蛛精, 孙悟空, 猪八戒, 唐三藏, 沙师弟, 白龙马]
list.addLast("玉兔精");//添加尾元素
System.out.println(list);//[蜘蛛精, 孙悟空, 猪八戒, 唐三藏, 沙师弟, 白龙马, 玉兔精]
System.out.println(list.getFirst());//获取首元素,蜘蛛精
System.out.println(list.getLast());//获取尾元素,玉兔精
System.out.println(list.removeFirst());//删除首元素
System.out.println(list);//[孙悟空, 猪八戒, 唐三藏, 沙师弟, 白龙马, 玉兔精]
System.out.println(list.removeLast());//删除尾元素
System.out.println(list);//[孙悟空, 猪八戒, 唐三藏, 沙师弟, 白龙马]
System.out.println(list.element());//孙悟空,获取首元素
/*别名:查询系列*/
System.out.println(list.peek());//孙悟空,获取首元素
System.out.println(list.peekFirst());//孙悟空,获取首元素
System.out.println(list.peekLast());//白龙马,获取尾元素
/*别名:现在系列*/
System.out.println(list.offer("海绵宝宝"));
System.out.println(list.offerFirst("潘大星"));//添加首元素
System.out.println(list.offerLast("熊大"));//添加尾元素
System.out.println(list);
/*别名:删除系列*/
System.out.println(list.poll());//删除首元素
System.out.println(list.peekFirst());//删除首元素
System.out.println(list.pollLast());
}
}
6.Map接口
Map接口的特点
1.map集合的结构是:键值对、KEY与VALUE、Map.Entry<K,V>的映射关系
2. map中key值不允许重复,如果重复,对应的value会被覆盖
3. map中的映射关系是无序的
4. map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代
简单方法:
void clear() 清空集合
boolean equals(Object o) 判断集合对象与参数o是否相等
int hashCode() 返回本集合的哈希码值
boolean isEmpty() 判断集合是否为空
int size() 返回本集合中键值对的个数
map单个集合间的操作 :
boolean containsKey(Object key) 判断map中是否包含指定的key
boolean containsValue(Object value) 判断map中是否包含指定的value
V get(Object key) 根据指定的key返回对应的value,如果不存在,返回null
V remove(Object key) 删除本集合中参数key对应的键值对
V put(K key, V value) 向集合中添加映射关系(键值对)
void putAll(Map<> m) 向本集合中添加m集合的所有映射关系(键值对)
map的迭代 :
Collection values() 把本map中的Value值取出放入一个Collection中并返回这个Collection
Set keySet() 把本map中的Key值取出放入一个Set集合中并返回这个Set集合
Set<Map.Entry<K,V>> entrySet()
把本map中的每一对KV都看成是一个Entry,把所有的Entry取出放入一个Set集合中并返回这个Set集合
7.Set接口
Set接口的特点
1.set集合没有重复的元素
2. set集合的元素是无序的
3. set集合可以存null值,并且null最多有一个
4. 我们自定义对象如果想去重,需要在自定义类中添加重写的equals()与hashCode()
package cn.tedu.Collection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*本类用于测试set*/
public class TestSet {
public static void main(String[] args) {
//创建对应得集合对象
Set<String> set = new HashSet<>();
//存入数据
set.add("紫霞仙子");
set.add("至尊宝");
set.add("蜘蛛精");
set.add("紫霞仙子");
set.add("null");
/*1.set集合中的元素都是没有顺序的
* 2.set集合中的元素不能重复
* 3.set集合可以存null值,最多存一个*/
System.out.println(set);
System.out.println(set.contains("唐僧"));//false,判断是否包含指定元素
System.out.println(set.isEmpty());//false 判断集合是否为空
System.out.println(set.remove("null"));//删除集合中的指定元素
System.out.println(set);
System.out.println(set.size());//获取集合中元素的数量
System.out.println(Arrays.toString(set.toArray()));//[蜘蛛精, 至尊宝, 紫霞仙子]
//集合间的操作
Set<String> set2 = new HashSet<>();
set2.add("小兔纸");
set2.add("小脑斧");
set2.add("小海藤");
set2.add("小狮几");
System.out.println(set2);
set2.addAll(set);
System.out.println(set2);
//判断集合1中是否包含集合2的元素
System.out.println(set.containsAll(set2));//false
//移除集合2中属于集合1的所有元素
System.out.println(set2.removeAll(set));
System.out.println(set2);
//取set2集中中属于set集合的公共元素
System.out.println(set2.retainAll(set));
System.out.println(set2);//[]
System.out.println(set);
//获取迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()){
String next = it.next();
System.out.println(next);
}
}
}
8.集合学习的方法
学习父级的公共方法,学习子类的创建方式,学习各种集合的特点
1.关于List大多都是与下标有关的操作
2. 关于Set通常都是去重的操作
3. 关于map通常都是映射关系,也就是键值对
4. API要常练习,方法互相之间没有任何关系,用哪个,查哪个