一、接口
(一)概述
1、广义:一切定义规则的事物都是接口
2、侠义:Java中用于定义方法声明的规则就是接口,Java的接口中,定义的所有方法都是抽象的
3、好处:将方法的调用和方法的实现分离开了吗,可以降低代码的耦合度,提升开发效率
(二)接口的特点
1、定义格式
public interface 接口名{}
2、接口中只能声明定义抽象方法,不能有方法的实现
3、接口的实现,使用类,用过implements关键字来实现接口
(1)格式
class 类名 implements 接口名 { }
(2)接口中只有方法的声明没有实现,我们通过类来实现接口,不同的类可以实现相同的接口,给予接口不同的实现
4、接口实现类的用于
(1)当接口的实现类实现了接口中所有的抽象方法,这个类就是一个普通类,可以创建对象调用方法
(2)当接口的实现类没有完全实现接口中的抽象方法时,那么此时这个类就是一个抽象类,就需要进一步通过子实现类继承抽象类中的抽象方法
package com.hqyj.demos;
public class Demo01_Inter {
}
/**
* 接口
*/
interface MyInter {
public abstract void test1();
public abstract void test2();
}
abstract class MyClass implements MyInter {
@Override
public void test1() {
//当抽象类实现了接口中的一部分抽象方法的时候,子实现类就可以不同实现这部分
}
}
class MySon extends MyClass {
@Override
public void test2() {
}
}
(三)接口中成员特点
1、成员变量:没有。接口中只能定义常量不能定义变量!当我们定义一个常量时,会默认加上【public static final】,建议手动加上
2、成员方法:只有抽象方法。默认会省略【public abstract】建议手动加上
3、构造方法:没有。接口中不能定义变量,没有赋值的需求
package com.hqyj.demos;
public class Demo02_InnerInterface {
}
interface MyInter01 {
//常量
public static final int MAX = 100;
//静态方法
public static void test2() {}
//成员变量
//String name;
//成员方法
//public void test() {}
//抽象方法
public abstract void test1();
//构造方法
//public MyInter01() {}
}
(四)类与类、类与接口、接口与接口
1、类与类:继承关系,使用关键字extends,支持:单继承、多层继承
2、类与接口:实现关系,使用implements关键字
(1)支持单实现、多实现;
(2)单实现:
class 类名 implements 接口名 {
实现接口中所有的抽象方法
}
abstract class 类名 implements 接口名 {
实现接口中部分的抽象方法
}
(3)多现实
class 类名 implements 接口名1, 接口名2, 接口名3... {
实现所有接口中所有的抽象方法
}
abstract class 类名 implements 接口名1, 接口名2, 接口名3... {
实现接口中部分的抽象方法
}
(4)一个类在实现多个接口的同时,还可以继承一个类
class 类名 extends 父类 implements 接口名1, 接口名2, 接口名3... {
实现所有接口中所有的抽象方法
重写父类中的方法
}
abstract class extends 父类 类名 implements 接口名1, 接口名2, 接口名3... {
实现接口中部分的抽象方法
重写父类中的方法
}
3、接口与接口:继承关系,支持:单继承、多继承、多层继承
(1)多继承的格式
interface 接口 extends 接口名1, 接口名2, 接口名3... {
相当于整合了所有接口中的抽象方法
}
4、设计思路
(1)类一般用于定义事物固有的属性和行为
(2)接口一般用于定义事物通过扩展获取学习而来的功能
二、多态
(一)概述
1、多态:事物的多种状态
2、对象的多态性:同一个对象,可能具有不同的名称,可以有不同的类型的引用指向他。本质:同一个对象,有不同的名称和描述
3、类的多态性:同一个类型,可能还具有不同的子类,同一个类型的引用,可以指向不同的子类对象。本质:同一个名字和描述,可能在不同的场景下有不同的实现。
4、多态的前提
(1)要有继承关系
(2)有方法的重写
(3)父类引用指向子类对象
(二)成员变量的特点
1、编译看左边,运行看左边
2、编译看左边:如果左侧父类中没有定义相关的变量,编译期就会报错
3、运行看左边:如果左侧有对应的成员变量,就会执行父类中的成员变量
package com.hqyj.demos;
public class Demo04_Fields {
public static void main(String[] args) {
//父类引用指向子类对象
//成员变量是从一个类的角度去描述一个对象
Person01 p = new Student();
System.out.println(p.name);
}
}
class Person01 {
String name = "人类";
}
class Student extends Person01 {
String name = "学生";
}
(三)成员方法的特点
1、编译看左边,运行看右边
2、编译看左边:如果左侧父类中没有定义相关的方法,编译期就会报错
3、运行看右边:如果右侧所属类型中有对应的方法,就执行对象所属类型中的方法
package com.hqyj.demos;
public class Demo05_Method {
public static void main(String[] args) {
Person02 p = new Student02();
p.test();
}
}
class Person02 {
public void test() {
System.out.println("父类中的方法执行了");
}
}
class Student02 extends Person02 {
public void test() {
System.out.println("子类中的方法执行了");
}
}
(五)多态的好处
1、提供了代码的可扩展性
2、在方法的参数列表中定义父类的引用,将来传入子类的对象都可以使用
(六)instanceof
1、instanceof,关键字:是一个运算符,结果是一个布尔类型的值
2、格式
A instanceof B
3、作用:A是一个对象,B是一个类型;判断A对象是否和B类型有关;
4、有关:A对象是B类型的对象;A对象是B类型子类的对象
package com.hqyj.demos;
public class Demo08_Instanceof {
public static void main(String[] args) {
Painter p = new Painter();
p.drawPicture(new Pen());
p.drawPicture(new DrawPen());
p.drawPicture(new Brush());
p.drawPicture(new EyePen());
}
}
/**
* 笔的总父类
*/
class Pen {
public void write() {
System.out.println("画出印记");
}
}
/**
* 眼线笔类
*/
class EyePen extends Pen {
}
/**
* 画笔类
*/
abstract class Pencil extends Pen {
public abstract void drawing();
}
/**
* 毛笔类
*/
class DrawPen extends Pencil {
@Override
public void drawing() {
System.out.println("画水墨画");
}
}
/**
* 排笔
*/
class Brush extends Pencil {
@Override
public void drawing() {
System.out.println("画油画");
}
}
/**
* 画家类
*/
class Painter {
public void drawPicture(Pen p) {//Pen p = new Pen();
//判断当前的笔能不能画画
if (p instanceof Pencil) {
//如果是画笔类的对象,就可以画画
//因为执行的方法是子类特有的方法,所以需要进行类型转换
Pencil pe = (Pencil) p;
pe.drawing();
} else {
p.write();
}
}
}
三、final关键字
1、final:关键字,含义:不可更改的
2、可以修饰的内容
(1)修饰类:类不能被继承
(2)修饰成员变量:变量变为常量
(3)修饰方法:方法不能被重写
3、final通常被用在定义常量【public static final int MAX = 100;】
四、内部类
(一)概述
1、概述:定义在类的内部的类,和方法、变量等,均作为类的成员
2、根据定义位置的不同,分为:
(1)成员内部类
(2)局部内部类
3、成员内部类:
(1)普通成员内部类
(2)私有成员内部类
(3)静态成员内部类
4、根据表示方式的不同:
(1)有名字的内部类
(2)匿名内部类
(二)普通成员内部类
1、定义在类成员位置的类,就是成员内部类
2、格式:
class 外部类类名 {
外部类成员;
class 内部类类名 {
内部类成员;
}
}
(三)私有成员内部类
1、在普通成员内部类的声明上加上private关键字
2、格式:
class 外部类类名 {
外部类成员;
private class 内部类类名 {
内部类成员;
}
}
(四)静态成员内部类
1、格式:
class 外部类类名 {
外部类成员;
static class 内部类类名 {
内部类成员;
}
}
(五)局部内部类
1、概述:定义在方法中的类
2、访问说明
(1)方法中的局部变量在方法外不能被访问,局部内部类与局部变量同作为方法的成员,在方法之外不能访问,所以局部内部类在方法以外没有任何访问方式,并且必须先定义后调用;类似局部变量的先赋值后调用
(2)解决方式:只能执行局部内部类所在的方法,在方法中创建局部内部类的对象,对调用其中的内容进行执行
(六)匿名内部类
1、概述:没有名字的内部类
2、使用场景
(1)实现抽象类
(2)实现接口
3、格式
new 抽象类类名或者接口名() { 要实现的抽象方法; };
4、本质:
(1)匿名内部类本质上是一个实现类对象
(2)编译之后也会生成一个.class文件
5、class文件命名
(1)有名字的内部类:
-
成员内部类:外部类类名$内部类类名.class
-
局部内部类:外部类类名$1内部类类名.class【Body03$1Heart03.class】
(2)匿名内部类:所在类类名$1.class【Demo04_NoNameClassAndInter$1.class】
五、Object
(一)概述
1、Object是所有类层次结构的根类,是所有类的直接或者间接父类
2、随意定义一个类型,不显示继承哪个类,就默认继承Object类
(二)常用方法
1、[getClass]:获取当前对象所属的类型
2、[hashCode]:根据对象的情况,计算对象的哈希码值
3、[toString]:重写后:返回对象的字符串表示形式
4、[finalize]:当垃圾回收器确定后面该对象不再被使用的时
候,就有该对象的垃圾回收器调用此方法,清理空间(对象)
(三)equals方法
1、用于比较两个对象是否相等,这两个对象为调用者对象和参数对象
2、在Object类型中,比较的是两个对象的地址值是否相等
3、在所属类型中重写equals方法之后,比较的是地址值
package com.hqyj.demos;
import java.util.Objects;
public class Demo06_Equals {
public static void main(String[] args) {
Student stu1 = new Student("张三", 23);
Student stu2 = new Student("张三", 23);
System.out.println(stu1.equals(stu2));
}
}
class Student {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
(四)==和equals的区别
1、共同点:都是用于比较数据是否相等的方式
2、不同点:
(1)==:是一个运算符;equals:是一个方法
(2)==:可以比较基本数据类型,也可以比较引用数据类型;equals:只能比较引用数据类型
(3)==:比较基本数据类型比较属性值,比较引用数据类型比较地址值;equals:重写前比较地址值,重写后比较属性值
六、StringBuilder
(一)概述
1、StringBuilder是一个可变字符序列,因为在类中提供了对应修改的方法
2、StringBuilder底层是数组,封装了对底层操作的方法
(二)构造方法
1、[StringBuilder]():创建一个字符串生成器,初始容量为16
2、[StringBuilder](int capacity):创建一个字符串生成器,初始容量为参数指定
3、[StringBuilder](String str):创建一个字符串生成器,初始容量为16+str的长度
4、[capacity]():返回字符串生成器的容量
5、[length]():返回字符串缓冲区中字符的个数
package com.hqyj.demos;
public class Demo07_StringBuilder {
public static void main(String[] args) {
//初始容量为16
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
System.out.println(sb.length());
StringBuilder sb1 = new StringBuilder(10);
System.out.println(sb1.capacity());
System.out.println(sb1.length());
StringBuilder sb2 = new StringBuilder("abc");
System.out.println(sb2.capacity());
System.out.println(sb2.length());
}
}
(三)添加功能
1、[append](int i):将任意类型的参数追加到当前课表字符序列之后
2、底层操作:当字符串个数和当前数组容积进行比较,如果溢出,就做数组的拷贝,将原有数组
的内容添加到新的数组中,其中,新数组的容积为【原来容积<< 1 + 2】
3、[insert](int offset, int i):任意数据类型插入到指定位置
package com.hqyj.demos;
public class Demo08_Append {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println(sb.capacity());
for (int i = 1; i <= 71; i++) {
//sb.append("1");
sb.insert(0, "1");
}
//16 34 70 142 286 [<< 1 + 2]
System.out.println(sb.capacity());
}
}
(四)StringBuilder和StringBuffer
1、共同点:都是可变字符序列,都是字符串生成器,都是字符串缓冲区
2、不同点:
(1)线程安全性不同
-
StringBuilder:安全性低
-
StringBuffer:安全性高
(2)效率不同:
-
StringBuilder:效率高
-
StringBuffer:效率低
(3)版本
-
StringBuilder:JDK1.5
-
StringBuffer:JDK1.0
七、异常
(一)概述
1、在Java运行过程中,出现了不正常的情况,称为异常
2、异常就是一个对象,描述的是那些和正常情况不相符的情况
3、异常也是一种处理异常情况的机制,可以对异常对象进行捕获、或者使程序发生跳转甚至停止
(二)体系结构
1、Throwable:可抛出的,是异常体系和错误体系的总父类
2、Error:错误;用于描述那些无法捕获和处理的错误情况,属于非常严重的错误
3、Exception:异常;拥有描述那些可以被捕获和处理的异常情况,属于不太严重的情况
4、RuntimeException:是Exception的子类,它的子类都是运行时异常,在Exception中除了
RunTimeException之外都是编译时异常
(三)JVM默认处理异常机制
JVM默认处理异常的方式:一层一层往上抛,JVM接收到之后将异常信息打印在控制台
(四)手动处理异常的方式
1、有两大类的处理异常的方式
(1)异常的声明:某个方法存在编译时异常,编译期无法通过的时候,需要在编译时异常的方法声明上,对可能发生异常的类型进行声明
(2)异常的捕获:出现异常情况之后,可以通过某段代码格式对异常对象进行捕获和处理;此时,程序出现的异常对象,就不会再往上抛了,而是捕获下来了
2、捕获格式
(1)try...catch
(2)try...catch...catch...catch
(3)try...catch..finally
(4)try...finally
(五)try...catch
1、try:关键字;含义:试一试,可能出现问题的代码放在try模块中
2、catch:关键字;含义:捕获;当真的出现问题之后应该怎样去处理
3、格式:
try {
可能出现问题的代码;
} catch(可能出现异常的类型 标识符) {
出现了这种问题之后处理方式;
}
package com.hqyj.demos;
public class Demo02_TryCatch {
public static void main(String[] args) {
/**
* try {
* 可能出现问题的代码;
* } catch(可能出现异常的类型 标识符) {
* 出现了这种问题之后处理方式;
* }
*
* 1、try模块中除零异常之后的代码,不能执行
* 2、try...catch模块之后的代码正常执行
* 3、如果没有异常情况,try中的代码正常执行,catch中的代码不执行
* 4、try模块中可能出现的异常类型必须和catch模块中对应,或者是其父类
* 5、当catch中接收异常情况的时候,发现类型不匹配,就会按照默认的处理方式进行处理
*/
try {
//System.out.println(10 / 0);
System.out.println("try模块中除零异常之后的代码,不能执行");
System.out.println("111");
//try模块中可能出现的异常类型必须和catch模块中对应,或者是其父类
} catch (Exception ae) {
ae.printStackTrace();
}
System.out.println("除零异常之后的代码,可以执行");
}
}
(六)try...catch...catch
1、概述:一段代码中可能出现多个异常信息,这个时候就需要多个异常类型进行接收
2、格式:
try {
可能出现问题的代码;
} catch(可能出现异常的类型1 标识符) {
出现了这种问题之后处理方式1;
} catch(可能出现异常的类型2 标识符) {
出现了这种问题之后处理方式2;
} catch(可能出现异常的类型3 标识符) {
出现了这种问题之后处理方式3;
}
(七)try...catch..finally
1、finally:关键字;含义:最后,当代码中有必须要执行的代码的时候,放在finally模块中
2、格式
try {
可能出现问题的代码;
} catch(可能出现异常的类型 标识符) {
出现了这种问题之后处理方式;
} finally {
必须要执行的代码;
}
package com.hqyj.demos;
public class Demo04_TryCatchFinally {
public static void main(String[] args) {
/**
* 1、finally模块中放的是必须要执行的代码块,一般用于关闭资源
* 2、如果有多个异常都需要判断的时候,就可以在finally模块中进行其他异常的处理
*/
try {
//return;
//System.exit(0);
//可能出现异常的代码
System.out.println(10 / 0);
} catch (ArithmeticException e) {
e.printStackTrace();
} finally {
System.out.println("finally中的代码执行了");
//可能出现异常的代码
try {
String str = null;
System.out.println(str.charAt(0));
} catch (NullPointerException e) {
e.printStackTrace();
}
}
System.out.println("异常处理之后的代码执行了");
}
}
(八)try...finally
1、格式:
try {
可能出现问题的代码;
} finally {
必须要执行的代码;
}
(九)throw关键字
1、throw:关键字;含义:抛出,用于抛出一个异常对象
2、作用:创建一个异常对象,使用throw关键字抛出,实现程序的跳转
3、说明:当代码正常运行的时候,运行时异常不会发生,就相当于没有任何异常对象;当代码中
出现了异常的情况,就会创建对象对异常信息进行处理
(十)throws关键字
1、throws:关键字;含义:抛出,用于声明一个或者多个异常类型
2、在某个方法中,如果存在一些编译时异常,并且这些编译时异常还未处理,就会报错阻止编
译,我们就必须对这些编译时异常进行处理;捕获或者声明
3、声明:就是在方法的声明上,参数列表之后,跟上关键字throws,并且注明声明一个或者多个
异常类型
4、格式:
修饰符 【static】 返回值类型 方法名(参数列表) throws 异常类型1, 异常类型2... {
}
5、如果某个方法中出现了编译时异常,并且处理的方式是声明,其他方法在调用该方法的时候也
需要进行异常的处理
6、如果某个方法中出现了编译时异常,并且处理的方式是捕获,那么后续别的方法在调用的时候
就不需要进行异常的处理
7、异常声明原则:尽量声明少的、声明小的异常
(十一)throw和throws
1、throw是对已经出现的异常对象进行抛出,throws关键字是对可能发生的异常类型进行声明
2、throw是对异常对象实实在在的抛出,一旦执行到了throw关键字,就一定会有一个异常对象出现,throws关键字是对多个可能出现的异常类型的声明,即使声明多个异常类型,也有可能一个都不发生
3、throw后面跟的是一个异常对象;throws后面跟的是一个或者多个异常类型
4、异常声明原则:尽量声明少的、声明小的异常
(十二)自定义异常
1、官方提供的异常类型有限,可能不能满足日常开发需求,如果自己想要说明出现的问题是什么
就需要自定义类型异常,对异常情况进行详细的描述
2、步骤:
(1)创建一个异常类型,类名做到见名知意
(2)需要让自定义类型异常加入异常体系
- 如果自定义类型异常是运行时异常:就继承RuntimeException
- 如果自定义类型异常是编译时异常,就继承Exception
(3)因为所有异常都是为了方便统一处理,都会使用到Throwable中的方法,并且为了以后方便
创建异常对象和处理异常对象,根据父类构造方法的情况,提供相应的构造方法
八、集合
(一)概述
概述:也是一个类似于数组的统一存储和管理数据的容器,集合只能存储引用数据类型,不能存储基本数据类型,就类似于对象数组
(二)优势
1、可扩展性:底层会自动增长,不用我们自行扩展
2、集合中存储了大量用于操作集合的方法
3、集合存储的是引用数据类型,以及对象;利于我们面向对象的思想
4、不带泛型的集合可以存储任何数据类型
(三)集合体系
1、分类:·
(1)单列集合:每一个元素都是一个单独的个体,就类似于数组一样
(2)双列集合:每一个操作都针对一对数据进行,以一对数据为单位
九、Collection接口
(一)概述
1、Collection,接口名;含义:收集、集合
2、单列集合的顶层接口,定义了所有单列集合共有的方法
3、接口不能创建对象,需要子实现类类创建对象调用方法:接口Collection的引用,指向实现类ArrayList对象
4、常用方法:
(1)[add](Object obj):将obj元素添加到集合中
(2)[remove](Object o):将指定元素从集合中删除
(3)[clear]():移出此集合中所有的元素
(4)[isEmpty]():判断集合是否为空
(5)[contains]((Object o):判断集合中是否包含指定元素
(6)[size]():返回集合的个数
package com.hqyj;
import java.util.ArrayList;
import java.util.Collection;
public class Demo01_Collection {
public static void main(String[] args) {
Collection list = new ArrayList();
//(1) add(Object obj):将obj元素添加到集合中
list.add("qwe");
list.add(234);
list.add('Q');
list.add("^&*");
list.add("qwe");
System.out.println(list);
//(2) remove(Object 0):将指定元素从集合中删除
list.remove('Q');
System.out.println(list);
//(3) clear(): 移出此集合中所有的元素
list.clear();
//(4) isEmpty!(): 判断集合是否空
System.out.println(list.isEmpty());
//(5) contains(Object 0):判断集合中是否包含指定元素
System.out.println(list.contains(234));
//(6) size(): 返回集合的个数
System.out.println(list.size());
}
}
(二)第一种遍历
1、[toArray]():将集合中的元素添加到一个数组并返回
2、调用此方法,将集合元素存储在数组中,再对数组进行遍历
import java.util.ArrayList;
import java.util.Collection;
public class Demo02_ToArray {
public static void main(String[] args) {
Collection list = new ArrayList();
//(1) add(Object obj):将obj元素添加到集合中
list.add("qwe");
list.add(234);
list.add('Q');
list.add("^&*");
list.add("qwe");
Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
(三)第二种遍历:迭代器
1、迭代器:专门用于将集合中的元素,一个到另一个迭代的对象
2、迭代器的获取:iterator(),集合通过调用方法获取迭代器对象
3、迭代器的使用
(1)hasNext():判断是否有下一个可以迭代的元素,如果有返回true
(2)next():获取集合中的下一个元素
(3)remove():删除集合中迭代器正在迭代的这个元素
4、注意
(1)hasNext():每次只能判断下一个元素是否存在
(2)next():每次只能获取一个元素并且将迭代器向下一个元素移动一个位置
(3)调用一次hasNext方法只能调用一次next方法
package com.hqyj.demos; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class Demo03_Iterator { public static void main(String[] args) { Collection coll = new ArrayList(); coll.add(new Person("张三", 23)); coll.add(new Person("李四", 24)); coll.add(new Person("王五", 25)); //coll.add(new Person("赵六", 26)); //1、获取迭代器对象 Iterator it = coll.iterator(); //2.判断还有没有下一个元素 while (it.hasNext()) { //3、获取下一个元素 Object next = it.next(); //4、向下转型,执行子类特有的方法 Person p = (Person) next; System.out.println(p.getName() + "..." + p.getAge()); // 禁止书写 当调用一次hasNext方法的时候,只能调用一次next()方法 // System.out.println(((Person) it.next()).getName() + "..." + ((Person) it.next()).getAge()); } } }
十、List接口
(一)概述
1、是Collection的子接口
2、特点:
(1)有序:元素存储顺序和读取顺序一致
(2)可重复:允许存储重复的元素
3、常用方法:
(1)[add](int index, E element):将指定元素插入到集合的指定位置
(2)[remove](int index):删除指定索引上的元素
(3)[set](int index, E element):用指定元素替换指定索引上的元素
(4)[get](int index):返回指定索引上的元素
(二)第三种遍历
1、针对List集合特有的遍历方式,Collection中不一定能使用,Set中肯定不能使用
2、可以通过size方法获取集合的长度,进而就可以得到集合的索引范围,再配个get方法获取指定
索引上的元素,就能获取到每一个索引上对应的元素
package com.hqyj.demos;
import java.util.ArrayList;
import java.util.List;
public class Demo04_PrintList {
public static void main(String[] args) {
List list = new ArrayList();
list.add("qwe");
list.add(234);
list.add('Q');
list.add("^&*");
list.add("qwe");
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.println(o);
}
}
}
(三)并发修改异常
1、ConcurrentModificationException
并发 修改 异常
2、出现原因:在使用迭代器进行遍历的时候,通过集合对象操作集合
3、避免方式:
(1)集合遍历,集合操作
(2)迭代器遍历,迭代器操作
4、[listIterator]():List集合特有迭代器,操作和以前一样,只不过提供了更多的操作集合的方法
十一、基本数据类型包装类
(一)概述
1、基本数据类型有八种
2、集合中只能存储引用数据类型,不能存储基本数据类型,如果需要将基本数据类型存储在集合中,就需要对基本数据类型进行封装
十二、List的实现类
(一)概述
1、List是一个接口,无法直接创建对象,所以根据它的实现类不同,具有不同的特点
2、ArrayList:数组实现,顺序存储
3、Vector:数组实现,顺序存储
4、LinkedList:链表实现,节点存储
(二)ArrayList
1、概述
1、是List的实现类
2、存储方式:
(1)数组实现,顺序存储
(2)增删慢,查询快;增删慢是因为有索引,增加或者删除一个元素之后,索引需要重新排列,
比较慢;查询快:是因为有索引,可以直接找到对应索引的元素
(3)通过物理内存结构实现位置关系,来表达逻辑上的相邻
(三)LinkedList
1、List接口的实现类
2、存储方式:
(1)节点实现,链式存储
(2)不是通过物理结构实现的相邻关系,是通过逻辑结构实现的相邻
(3)每一个节点,存储了元素以及相邻节点的地址值,通过地址值实现前后的相邻关系
3、特点
(1)查询慢:需要根据前面的节点获取下一个节点的地址,前面所有的节点都需要过一遍,节点
越多,查询速度越慢
(2)增删快:增加或者删除一个元素,只需要断开相邻节点的连接,在相邻节点中添加新的地址
值即可
4、特有方法
(1)[addFirst](E e):将指定元素插入到列表头部
(2)[addLast](E e):将指定元素插入到列表尾部
(3)[getFirst]():获取头部元素
(4)[getLast]():获取尾部元素
(5)[removeFirst]():删除头部元素并返回
(6)[removeLast]():删除尾部元素并返回