Java面向对象的三条主线:

  1. Java类及类的成员:属性、方法、构造器;代码块、内部类
  2. 面向对象的三大特征:封装性、继承性、多态性、(抽象性)
  3. 其他关键字:this、super、static、final、abstract、interface、package、improve

面向对象的两个要素

1、类和对象

类:对于类事物的描述,是抽象的、概念上的定义

  • 属性(成员变量)
  • 方法(成员方法)

对象:是实际存在的该类事物的每个个体,因此也称为实例(instance)

  • 创建类的对象=类的实例化=实例化类

面向对象程序设计的重点是类的设计

设计类,就是设计类的成员

2、类和对象的使用(面向对象思想落地的实现)

  1. 创建类,设计类的成员
  2. 创建类的对象
  3. 通过”对象.属性“和”对象.方法“调用对象的结构

3、一个类创建多个对象

  1. 如果创建了一个类的多个对象,则每个对象都有独立的拥有一套类的属性(非static的)
  2. 这也就意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值

1.Java基础语法

1.1标识符

  • Java所有的组成部分都需要名字。类名、变量名以及方法名都被 称为标识符

注意点

  • 不能使用关键字作为变量名或方法名

1.2数据类型

  • 强类型语言(Java)
    • 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
  • 弱类型语言(JavaScript)

Java的两大数据类型

  1. 基本数据类型
    • 数值类型
      • 整数类型
        • byte占1个字节范围
        • short占2个字节范围
        • int占4个字节范围
        • long占8个字节范围(要在数字后面加个L)
      • 浮点类型
        • float占4个字节
        • double占8个字节(要在数字后面加个F)
      • 字符类型
        • char占2个字节
    • Boolean类型:占1位其值只有true和false两个
  2. 引用数据类型
    • 接口
    • 数组

注意

  • string,字符串,不是关键字,是类

1.3什么是字节

  • 位(bit):是计算机内部数据储存的最小单位,11001100是一个八位二进制数
  • 字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示
  • 1B(byte,字节) = 8 bit(位)】、
  • 字符:是指计算机中使用的字母、数字、字和符号
  • 1bit表示1位
  • 1byte表示一个字节 1B=1b
  • 1024B=1KB
  • 1024KB=1M
  • 1024M=1G

1.4类型转换

  • 由于Java是强类型语言,所以有些在进行运算的时候,需要用到类型转换
    • 低————————————–>高
    • byte,short,char—>int—>long—->float—>double
  • 运算中,不同类型的数据先转化为同一类型,然后进行运算
  • 强制转换 (类型)变量名 高——>低
  • 自动转换 低——->高

注意

  1. 不能对布尔值进行转换
  2. 不能把对象类型转换为不相干的类型
  3. 在把高容量转换到低容量的时候,强制转换
  4. 转换的时候可能存在内存溢出,或者精度问题

1.5变量

  • 概念:可以变化的量
  • Java是一种强类型的语言,每个变量都必须声明其类型
  • Java变量是程序中最基本的存储单元,其要素包括变量名、变量类型和作用域
  • 数据类型 变量名 = 值;

注意事项

  1. 每个变量都有类型 ,类型可以是基本类型,也可以是引用类型
  2. 变量名必须是合法的标识符
  3. 变量声明是一条完整的语句,因此每一个声明都必须以分号结束

1.6变量作用域

  • 类变量:static关键字
  • 实例变量:从属于对象
  • 局部变量:方法里的变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Demo01 {
//属性:变量
//类变量 static
static String name = "张三";

//实例变量:从属于对象
int age = 13;

public static void main(String[] args) {
//局部变量:必须声明和初始化值
char h = '中';
System.out.println(h);
System.out.println(name);
shout();
Demo01 demo01 = new Demo01();
System.out.println(demo01.age);

}

public static void shout(){
//局部变量
String name = "王五";
System.out.println(name);
}
}

1.7自增和自减

1
2
3
4
5
6
7
8
9
10
public class Demo02 {
public static void main(String[] args) {
int a = 3;
int b = a++;//执行完语句后,先给b赋值,再自增
int c = ++a;//执行完语句前,先自增,后给c赋值
System.out.println(c);
System.out.println(b);
System.out.println(a);
}
}
  • 自减类似

1.8三元运算符

1
2
3
4
5
6
7
8
9
10
11
12
//三元运算符
public class Demo03 {
public static void main(String[] args) {
int num = 80;
String all = num > 60 ? "及格": "不及格";
System.out.println(all);

//x ? y : z
//如果x==true 则为y 否则为z
}
}

2.Java流程结构

2.1scanner对象

  • 我们可以通过scanner类来获取用户的输入
  • 通过scanner类的next()与nextLine()方法获取输入的字符串,也可以再读取前使用hasNext()或者hasNextLine()判断

next()

  • 一定要读取到有效字符后才可以结束输入
  • 不能得到带有空格的字符串
  • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符

nextLine()

  • 可以获得带有空格的字符串

三种案例

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
//创建一个扫描器对象,键盘接收数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接受:");
//判断用户有没有输入字符串
if (scanner.hasNext()){
String next = scanner.next();//程序等待用户输入完毕
System.out.println("输出的内容:"+next);
}
scanner.close();//释放资源
}
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接受:");
//判断用户有没有输入字符串
if (scanner.hasNextLine()){
String s = scanner.nextLine();
System.out.println("输出的内容"+s);
}
scanner.close();
}
1
2
3
4
5
6
7
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入的内容是");
String s = scanner.nextLine();
System.out.println("输出的内容是"+s);
scanner.close();
}

判断整数

1
2
3
4
5
6
7
8
9
10
11
12
13

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入整数:");
//判断是否是整数
if (scanner.hasNextInt()){
int next = scanner.nextInt();
System.out.println("请输入整数"+next);
}else {
System.out.println("你输入的不是整数");
}
scanner.close();
}

输入多个数字,求输入数字总数和平均数,每输入一个数字回车确认,非数字来结束并输出执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {      
Scanner scanner = new Scanner(System.in);
//数
double i=0 ;
//和
double sum = 0;
while (scanner.hasNextDouble()){
double next = scanner.nextDouble();
i = i +1;
sum = sum + next;

}
System.out.println("个数为"+i);
System.out.println("平均数为"+sum/i);
scanner.close();
}

2.2if选择结构

if单选择结构

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int scope = scanner.nextInt();
if (scope>=60){
System.out.println("及格");
}else {
System.out.println("不及格");
}
scanner.close();
}

if多选择结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
if (score==100){
System.out.println("恭喜满分");
}else if (score<100 && score>=90){
System.out.println("优秀");
}
else if (score<90 && score>=80){
System.out.println("良好");
}
else if (score<80 && score>=70){
System.out.println("还行");
}
else if (score<70 && score>=60){
System.out.println("及格");
}else if (score<60 && score>=0){
System.out.println("不及格");
}else {
System.out.println("不合法");
}
scanner.close();
}

2.3switch选择结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
char grade= 'c';
switch (grade){
case 'a':
System.out.println("优秀");
break;
case 'b':
System.out.println("良好");
break;
case 'c':
System.out.println("及格");
break;
case 'd':
System.out.println("不及格");
break;
default:
System.out.println("不合法");
}
}

2.4while循环

while

1
2
3
4
5
6
7
8
9
10
11
12
//输出1~100的数字
public class Demo07 {
public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
System.out.println(i);
}

}
}

1
2
3
4
5
6
7
8
9
10
//输出1+2+3+......+100   
public static void main(String[] args) {
int i = 0;//初始化条件
int sum = 0;
while (i<=100){//判断条件
sum = sum + i;//循环条件
i++;//迭代
}
System.out.println(sum);
}

dowhile

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum = sum + i;
i++;
}while (i<=100);
System.out.println(sum);

}

两者区别

  • 对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次
  • do…..while循环至少执行一次
  • while先判断后执行,do….while是先执行后判断

案例

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
int i =0;
while (i<0){
System.out.println(i);
i++;
}
System.out.println("==========");
do {
System.out.println(i);
i++;
}while (i<0);
}

2.5for循环

语法格式

for(初始化;布尔表达式判断;更新){代码语句}

1
2
3
4
5
public static void main(String[] args) {
for (int i=0;i<=100;i++){
System.out.println(i);
}
}
  • 案例:计算0到100之间的奇数和偶数的和
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
int oddsum = 0;//奇数初始化
int evensum = 0;//偶数初始化
for (int i = 0; i <= 100; i++) {
if (i%2 !=0){
oddsum = oddsum +i;
}else {
evensum = evensum + i;
}
}
System.out.println("奇数的和为"+oddsum);
System.out.println("偶数的和为"+evensum);
}
  • 用for循环输出1到1000之间被5整除的数,并且每行输出3个
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
if (i%5==0){
System.out.print(i+"\t");//print表示不换行 \t表示tab
}
if (i%(5*3)==0){
System.out.println();//println表示换行
System.out.print("\n");//\n表示换行
}
}
}
  • 打印九九乘法表
1
2
3
4
5
6
7
8
9
10
11
12
13
//1、我们先打印第一列
//2、我们把固定的1再用一个循环包起来
//3、去掉重复项 i<=j
//4、调整样式
//内部for先执行完后才重新执行外面的
public static void main(String[] args) {
for (int j = 1; j <= 9; j++) {
for (int i = 1; i <= j; i++) {
System.out.print(j+"*"+i+"="+(j*i)+"\t");
}
System.out.println();
}
}

增强for循环

1
2
3
4
5
6
7
8
9
public class Demo10 {
public static void main(String[] args) {
int numbers[] ={10,20,30,40,50};
for (int number : numbers) {
System.out.println(number);
}
}

}

2.6break和continue

区别

  • break用于强行退出循环,不执行循环中剩余的语句
  • contunue用于终止某次循环,接着进行下一次是否执行循环的判定
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
int i = 0;

while (i<=10){
System.out.println(i);
i++;
if (i == 5){
break;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
int i = 0;

while (i<=10){
i++;
if (i == 5){
continue;
}
System.out.println(i);

}
}

3.7打印三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 5; j >= i; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
for (int j = 1; j < i; j++) {
System.out.print("*");
}
System.out.println();

}
}

3.java方法

3.1什么是方法

  • Java中方法是语句的集合,他们在一起执行的一个功能
  • 方法 包含于类或对象中
  • 方法在程序中被创建,在其他地方被引用
1
2
3
4
5
6
7
8
9
10
    public static void main(String[] args) {
//实际调用传递给形式参数的参数
int s = sum(10,23);

System.out.println(s);
}
//形式参数:用来定义作用
public static int sum(int a,int b){
return a+b;
}

形式参数和实际参数

  • 形式参数:用来定义作用
  • 实际参数:实际调用传递给形式参数的参数

3.2方法的定义和调用

分类

  1. 静态方法:可以直接在main方法直接调用

  2. 非静态方法:需要使用new关键字实例化一个对象,模板:对象类型 对象名=对象值

语法

  • 修饰符 返回值类型 方法名(参数类型 参数名){

    ​ 方法体

    ​ return 返回值;

    }

  • 修饰符:可选的

  • 返回值类型:除了void关键字不需要返回值,其他的都要

  • 方法名:可以是任意的

方法的调用

  • 对象名.方法名
  • 当方法返回一个值时,通常被当作一个值调用 例如:int sum = add(12,23);
  • 当方法返回值是void时,方法调用通常时一条语句 例如:add();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
int max =max(12,23);
System.out.println(max);

}
public static int max(int a,int b){
int result =0;
if (a==b){
System.out.println("a==b");
return 0;//终止方法
}
if ( a> b){
result = a;
}else {
result =b;
}
return result;
}

3.3方法重载

定义

  • 重载就是在一个类中,有相同的函数名称,但形参不同的函数

规则

  • 方法名必须相同
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同)
  • 返回值可以相同也可以不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void main(String[] args) {
double max =max(20,10);
System.out.println(max);

}
public static int max(int a,int b){
int result = 0;
if (a == b){
System.out.println("a==b");
return 0;
}
if (a>b){
result = a;
}else {
result = b;
}
return result;
}
public static double max(double a, double b){
double result = 0;
if (a>b){
result = a;
}else{
result = b;
}
return result;
}
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int s = sum(10,20,63);
System.out.println(s);
}
public static int sum(int a,int b){
return a+b;
}
public static int sum(int a,int b,int c){
return a+b+c;
}

4.数组

4.1什么是数组

  • 数组是相同类型数据的有序集合
  • 数组描述是相同类型的若干个数据,按照一定的先后顺序排列组合而成
  • 每一个数据称作一个数组元素,每一个数组元素可以通过一个下标来访问他们

4.2数组的创建和声明

语法

类型[] 名字 = new 类型[定义多少个]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public static void main(String[] args) {
//声明一个数组
int[] num;
num = new int[5];//创建一个数组
//给数组赋值
// num[0] = 1;
// num[1] = 2;
// num[2] = 2;
// num[3] = 2;
for (int i = 0; i < 5; i++) {
num[i]=i;
}
System.out.println(num[4]);
}

4.3数组的三种初始化

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
//静态初始化 创建+赋值
int[] a = {1,2,3,4,5,6};
System.out.println(a[3]);
//动态初始化:包括默认初始化
int[] b = new int[5];
b[2] = 5;
System.out.println(b[2]);
System.out.println(b[3]);//默认初始化0
}

  • 数组的默认初始化
    • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

4.4数组的基本特点

  1. 其长度是确定的,数组一旦被创建,他的大小就是不可以改变的
  2. 其元素必须是相同类型,不允许出现混合类型
  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型
  4. 数组变量属于引用类型,数组可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的

小结

  • 数组是想吐数据类型的有序集合
  • 数组也是对象,数组元素相当于对象的成员变量
  • 数组长度是确定的,不可变的,如果越界,则会报错

4.5数组的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
int[] a ={1,2,3,4,5,6,7,8};
//打印全部数组的元素
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
System.out.println("========");
//打印全部数组元素的和
int num = 0;
for (int i = 0; i < a.length; i++) {
num = num + a[i];
}
System.out.println(num);
System.out.println("==========");
//查找数组中元素最大的值
int max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i]>max){
max = a[i];
}
}
System.out.println(max);
}

4.6二维数组

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int[][] num= {{1,2},{2,3},{3,4},{4,5}};
for (int i = 0; i < num.length; i++) {
for (int j = 0; j < num[i].length; j++) {
System.out.println(num[i][j]);
}

}
System.out.println(num[0][1]);
}

4.7Arrays类

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
int[] a ={1,3,2,55,33,859,23,56};
//打印数组的所有元素
System.out.println(Arrays.toString(a));
//数组元素排序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
//数组元素填充0
Arrays.fill(a,0);
System.out.println(Arrays.toString(a));
}

4.8冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
int[] a= {2,443,23,45,654,23,1,54,56};
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));

}
public static int[] sort(int[] array){
//临时变量
int temp = 0;
//外层循环,判断我们这个要走多少次
for (int i = 0; i < array.length - 1; i++) {
//内层循环,比较判断两个数,如果第一个数比第二个数大,则交换位置
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j+1]>array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}

5.java面向对象编程(OOP)

5.1什么是面向对象

本质

  • 以类的方式组织代码,以对象的组织(封装)数据
  • 对象是具体的事物,类是抽象的,是对对象的抽象

三大特性

  • 封装、继承、多态

5.2类与对象的创建

类与对象的创建:

类:是一种抽象的数据类型,对某一事物整体的定义或描述

对象:抽象概念的具体实例(具体的事物),使用new关键词创建对象(实例化一个对象)

类:

修饰符 返回值类型 类名(){

属性(成员变量) 模板:修饰符 基本类型 属性名=属性值

方法体

}

New关键词创建时:

  1. 除了分配内存空间之外

  2. 给创建好的对象进行默认初始值

  3. 类中构造器的调用

形参和实参

  • 形式参数:用来定义的作用
  • 实际参数:用来实际调用传递给形式参数的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Demo06 {
String name;
int age;
public void say(){
System.out.println("学生在说话");
}

public static void main(String[] args) {
//类是抽象的,需要实例化
//类实例化返回一个自己的对象
//demo06对象就是Demo06类的具体实例
Demo06 demo06 = new Demo06();
demo06.name="小明";
demo06.age=19;
System.out.println(demo06.name);
System.out.println(demo06.age);
demo06.say();
}
}

5.3封装

  • 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用

定义

  1. 对数据的隐藏(通常是属性)

  2. 类部数据自己操作,暴露少部分方法给外部

  3. 用get/set()方法对其访问或调用

作用

  1. 提高程序的安全性
  2. 统一接口(get/set)
  3. 隐藏代码实现细节
  4. 提高系统维护性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.lesson4;
public class Demo4 {
private String name;

public String getName() {
return name;
}
public void setName(String name){
this.name = name;
}
}
==================================
package com.lesson4;
public class test {
public static void main(String[] args) {
Demo4 demo4 = new Demo4();
demo4.setName("小明");
System.out.println(demo4.getName());
}
}

5.4继承

  • 本质上对某一批类的抽象,从而实现对现实世界更好的建模
  • 类与类的继承
  • 父类与子类,子类继承父类(extends关键字)
  • Java中只有单继承没有多继承
  • 子类继承父类的所有方法
  • 所有的类都直接或间接继承object
  • 子类一般使用super调用父类的方法

父类

1
2
3
4
5
6
7
8
9
10
11
public class Person {
String name="小黑";

public Person() {
System.out.println("Person无参构造");
}

public void print(){
System.out.println("Person");
}
}

子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Student extends Person {
String name="小明";

public Student() {
//隐藏代码:调用了父类的无参构造
super();//调用无参构造,必须写在子类构造器的第一行
System.out.println("Student无参构造");
}

public void test1(){
print();
this.print();
super.print();
}

public void print(){
System.out.println("Student");
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);

}
}

测试类

1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
Student student = new Student();
// student.test("小河");
// student.test1();
}
}

5.5Super和This区别

Super注意点

1、super调用(继承)父类的构造方法,必须在子类的构造方法的第一个

2、Super必须只能在子类的构造方法中或方法中

3、Super和this不能同时调用

VS this

  • This:本身调用这个对象

  • Super:代表父类对象的引用

前提

  • This:没有继承也能使用
  • Super:只能在继承的条件下使

构造方法

  • this():本类的构造
  • super():父类的构造

5.6重写

前提

  1. 必须要有继承关系,子类重写父类的方法,执行子类的方法

  2. 参数列表必须相同

  3. 子类的方法和父类的方法名必须相同,但方法体不同

  4. 修饰符可以扩大不能缩小;public》protect》private

  5. 需要非静态方法

作用:

  • 父类的功能子类不一定需要

静态方法

  • 方法的调用只跟左边有关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.lesson4;
public class Application {
public static void main(String[] args) {
B b = new B();
b.say();
//父类的引用指向子类
A a = new B();
a.say();
}
}
===========================
package com.lesson4;
public class A {
public static void say(){
System.out.println("a");
}
}
=========================
package com.lesson4;

public class B extends A {
public static void say(){
System.out.println("b");
}
}
========
结果
b
a

方法重写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.lesson4;
public class Application {
public static void main(String[] args) {
B b = new B();
b.say();
//父类的引用指向子类
A a = new B();
a.say();
}

}
=================
package com.lesson4;

public class A {
public void say(){
System.out.println("a");
}
}
============
package com.lesson4;

public class B extends A {

@Override
public void say() {
System.out.println("b");
}
}
=========
结果
b
b

5.7多态

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(一般指有关系的类)

多态存在的条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

注意事项

  1. 多态指的是方法的多态
  2. 父类与子类关系,类型转换异常
  3. 存在条件:有继承关系(父类与子类)、方法的重写、父类引用指向子类对象
  4. 不能实现多态:static方法属于类不能实例化、final常量、私有private

父类

1
2
3
4
5
public class Person {
public void run(){
System.out.println("person");
}
}

子类

1
2
3
4
5
6
public class Student extends Person {
public void run(){
System.out.println("son");
}

}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {
public static void main(String[] args) {
Student student = new Student();
//父类引用子类
Person person = new Student();
student.run();
person.run();

}
}
=============
测试结果:
son
son

5.8类型转换

  • 子类转换为父类:向上转型:自动转换
  • 父类转换为子类:向下转型:强制转换、
  • 方便方法的调用,减少重复的代码

父类

1
2
3
4
5
public class Person {
public void run(){
System.out.println("person");
}
}

子类

1
2
3
4
5
6
7
8
public class Student extends Person {
public void run(){
System.out.println("son");
}
public void go(){
System.out.println("跑");
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {
public static void main(String[] args) {


// 低转高 自动转换 高转低 强制转换
// 高 <----- 低 自动转换
Person person = new Student();
person.run();
//低 <----- 高 强制转换
Student student = (Student)person;
student.go();

}
}

5.9抽象类

  • 约束,需要别人帮忙实现
  1. 不能使用new这个抽象类只能靠子类继承去实现
  2. 抽象类可以写普通的方法,但是抽象方法必须写在抽象类
  3. 抽象类只能单继承
  4. 抽象方法只有方法名,没有方法实现

5.10接口

  1. 接口不能被实例化,接口中没有构造方法

  2. Implement能实现多个接口

  3. 接口中定义的方法必须在implement重写接口中的方法

  4. 作用定义一些方法让不同的人实现

  5. 接口中的属性都是常量public static final

  6. 接口中定义方法都是抽象的public abstract

5.11构造器

定义

  • 必须和类的名字相同
  • 没有返回类型,也不能写void
  • 一个类即使什么都不写也存在一个无参构造器

作用

  • 用来初始化值
  • 使用new关键字实际上是在调用构造器(创建对象)

注意

  • 一旦定义了有参构造,用无参调用时必须显示无参构造
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.lesson4;
public class Demo2 {
public static void main(String[] args) {
Person person = new Person("xiaoming",12);
System.out.println(person.name);
System.out.println(person.age);
}
}
class Person{
String name;
int age;
//无参构造
public Person(){

}
//有参构造
public Person(String name,int age ){
this.name = name;
this.age = age;
}
}

6.集合

  • 集合、数组都是对多个数据进行存储操作的结构,简称Java容器
    • 此时存储,主要指的是内存层面的存储,不涉及到持久化存储

Java集合可分为collection和map两种体系

  • Collection接口:单列集合,用来存储一个一个的对象
    • List接口:存储有序的、可重复的数据 —->动态数组
      • ArrayList、LinkedList、Vector
    • Set接口:存储无序的、不可重复的数据——>高中讲的集合
      • HashSet、LinkedHashSet、TreeSet
  • Map接口:双列集合,用来存储一对一对的数据(key—value)—->高中的函数
    • HashMap、LinkedHashMap、TreeMap、HashTable、Preperties

6.1Collection常用的方法

  • 方法:add() size() isEmpty() clear() addAll()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class CollectionTest {
public static void main(String[] args) {

Collection coll = new ArrayList();
//将元素添加到集合collection中 add()
coll.add("aa");
coll.add("bb");
coll.add("cc");
//获取添加元素的个数size()
System.out.println(coll.size());
Collection coll1 = new ArrayList();
coll1.add("dd");
coll1.add("ee");
coll1.add("ff");
coll.addAll(coll1);
System.out.println(coll.size());
System.out.println(coll);
//清楚集合元素clear()
coll.clear();
//判断当前集合是否为空isEmpty()
System.out.println(coll.isEmpty());

}
}
  • 方法:contains() containsAll()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CollectionTest1 {

public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new java.lang.String("tom"));
coll.add(new Person("bob",12));
//判断当前集合中是否包含对象
//我们判断是会调用对象所在类的equals
System.out.println(coll.contains(new Person("bob",12)));
//判断形成coll1中的所有元素是否都存在于当前集合中
Collection coll1 = Arrays.asList(123,456);
System.out.println(coll.containsAll(coll1));
}


}
  • 方法:remove() removeAll() retainAll()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CollectionTest2 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new java.lang.String("tom"));
coll.add(new Person("bob",12));
//移除当前对象remove()
coll.remove(123);
System.out.println(coll);
//重写了equals,可以移除,否则不能
coll.remove(new Person("bob",12));
System.out.println(coll);
Collection coll1 = Arrays.asList(123,456);
//removeAll():差集,移除形参中的差集所有元素
coll.removeAll(coll1);
System.out.println(coll);
//retainAll():交集:获取当前集合和coll2集合的交集,返回当前集合
Collection coll2 = Arrays.asList(123,456,789);
coll.retainAll(coll2);
System.out.println(coll);
}
}
  • 方法equals:要想返回true,需要当前集合和形参集合的元素都相同
  • toArray() asList()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CollectionTest3 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new java.lang.String("tom"));
coll.add(new Person("bob",12));
//集合--->数组
Object[] array = coll.toArray();
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
//数组---->集合
List<String> list = Arrays.asList(new String[]{"AA", "BB", "cc"});
System.out.println(list);

}
}

6.2使用Iterator接口遍历collection集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CollectionTest4 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("tom"));
coll.add(new Person("bob",12));
//方法一:不推荐使用
Iterator iterator = coll.iterator();
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
//方法二:不推荐使用
// for (int i = 0; i < coll.size(); i++) {
// System.out.println(iterator.next());
// }
//方法三:推荐使用
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

6.3iterator的remove方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CollectionTest5 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("tom"));
coll.add(new Person("bob",12));

Iterator iterator = coll.iterator();
//移除元素
while (iterator.hasNext()){
Object next = iterator.next();
if (("tom").equals(next)){
iterator.remove();
}
}
//遍历元素
iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

6.4增强循环foreach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ForEachTest {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("tom"));
coll.add(new Person("bob", 12));
//for(集合元素的类型 局部变量 : 集合对象)
for (Object o : coll) {
System.out.println(o);
}
System.out.println("================");
//for(数组元素的类型 局部变量 : 数组对象)
int[] i = new int[]{1,2,3,4,5};
for (int s : i) {
System.out.println(s);
}
}
}

6.5List接口

list集合的实现方法

  • ArrayList:作为List接口的主要实现类;线程不安全,效率高,底层使用object[] elementData存储
  • LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高,底层使用双向链表存储
  • Vector:作为List接口的古老实现类;线程安全,效率低,底层使用object[] elementData存储

list接口的常用方法

  • 方法 add() addAll() get() indexOf() lastIndexOf() remove() set() subList()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class ListTest {
    public static void main(String[] args) {
    List list = new ArrayList();
    list.add(123);
    list.add(456);
    list.add(new String("tom"));
    list.add(new Person("bob", 12));
    list.add(456);
    System.out.println(list);
    //在index位置插入元素 add()
    list.add(1,666);
    System.out.println(list);
    //从index位置开始将集合中的所有元素添加进来 addAll()
    List list1 = Arrays.asList(555, 444);
    list.addAll(0,list1);
    System.out.println(list);
    //获取指定index位置的元素 get()
    System.out.println(list.get(0));
    //返回obj在集合中首次出现的位置 indexOf()
    int i = list.indexOf(123);
    System.out.println(i);
    //返回obj在当前集合中末次出现的位置 lastIndexOf()
    int j = list.lastIndexOf(456);
    System.out.println(j);
    //移除指定index位置的元素,并返回此元素remove()
    Object remove = list.remove(0);
    System.out.println(remove);
    System.out.println(list);
    //设置指定index位置的元素 set()
    Object set = list.set(0, 999);
    System.out.println(set);
    System.out.println(list);
    //返回从..到..左闭右开位置的子集合 subList()
    System.out.println(list.subList(0,4));


    }
    }

list集合遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ListTest1 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(new String("tom"));

//方式一 iterator迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("=================");
//方式二:增强for循环
for (Object o : list) {
System.out.println(o);
}
System.out.println("=================");
//方式三:普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}

常用方法:

  • 增 add(Object obj)
  • 删 remove(Object obj) / remove(int index)
  • 改 set(int index. Object obj)
  • 查 get(int index)
  • 插 add(int index, Object obj)
  • 长度 size()
  • 遍历
    • 方式一 iterator迭代器
    • 方式二:增强for循环
    • 普通for循环

6.6Set接口

Set集合实现类

Set接口:存储无序的、不可重复的数据

  • HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值
    • LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历
  • TreeSet:可以按照添加对象的指定属性,进行顺序

说明:Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法

Set接口:存储无序的、不可重复的数据

以HashSet为例说明:

  1. 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而实根据数据的哈希值决定的
  2. 不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SetTest {
public static void main(String[] args) {
Set set = new HashSet();
set.add(123);
set.add(456);
set.add(123);
set.add("aaa");
set.add("bbb");

Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
添加元素的过程:以HashSet为例

我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即:索引位置)判断数组此位置上是否已经有元素:

  • 如果此位置上没有其他元素,则元素a添加成功 情况1

  • 如果此位置上有其他元素b(或以链表形式村现在的多个元素),则比较元素a和元素b的hash值

    • ​ 如果hash值不相同,则元素a添加成功 情况2

    • ​ 如果hash值相同,进而需要添加元素a所在类的equals()方法

      • equals()返回true,元素添加失败
      • equals()返回false,元素添加成功
LinkedHashSet的使用
  • LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据
  • 有点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
TreeSet的自然排序和定制排序
  • 向TreeSet中添加的数据,要求时相同类的对象
  • 来两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator)
    • 自然排序中,比较两个对象是否相同的标准:compareTo()返回o;不再时equals()
    • 定制排序中,比较两个对象是否相同的标准:compare()返回o;不再时equals()

自然定制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Person implements Comparable {
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;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}

@Override
//按照姓名从小到大
public int compareTo(Object o) {
if (o instanceof Person){
Person person = (Person)o;
return this.name.compareTo(person.name);
}else {
throw new RuntimeException("输入的类型不匹配");
}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class SetTree {
public static void main(String[] args) {
Set set = new TreeSet();
set.add(new Person("bob",99));
set.add(new Person("jerry",15));
set.add(new Person("mike",16));
set.add(new Person("tom",17));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

定制排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class SetTree {
public static void main(String[] args) {
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o2 instanceof Person){
Person p1 = (Person)o1;
Person p2 = (Person)o2;
return Integer.compare(p1.getAge(),p2.getAge());
}else {
throw new RuntimeException("输入的数据类型不匹配");
}

}
};
Set set = new TreeSet(comparator);
set.add(new Person("bob",99));
set.add(new Person("jerry",15));
set.add(new Person("mike",16));
set.add(new Person("tom",17));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

6.7Map接口

map的实现类

Map接口:双列集合,用来存储一对一对的数据(key—value)key不可相同 value可相同

  • HashMap:作为Map的主要实现类:线程不安全,效率高,可以存储key和value

    • LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历

      原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素

      对于频繁的遍历操作,此类执行效率高于HashMap

  • TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序,底层使用红黑树

  • Hashtable:作为古老的而实现类:线程安全的,效率低,不能存储null的key和value

    • Properties:常用来处理配置文件。key和value都是string类型

HashMap的底层:数组+链表+红黑树(jdk8)

map结构的理解

map中key:无序的、不可重复的,使用set存储所有的key—>key所在的类要重写equals()和hashCode()

map中的value:无序的、可重复的,使用collection存储所有的value—–>value所在的类要重写equals

一个键值对:key-value构成了一个Entry对象

map的entry:无序的、不可重复的,使用set存储所有的entry

HashMap底层原理实现

jdk7为例: HashMap map = new HashMap()

在实例化以后,底层创建了长度是16的一维数组entry[] table

……可能已经执行过多次put….. map.put(key1,value1):

  • 首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在entry数组中的存放位置
    • 如果此位置上的数据为空,此时的key1-value1添加成功 情况1
    • 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:
      • 如果key1的哈希值与已经存在的数据的哈希值不相同,key1-value1添加成功 情况2
      • 如果key1的哈希值与已经存在的某个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)
        • 如果equals()返回false:此时key1-value1添加成功 情况3
        • 如果equals()返回true:使用value1替换value2
  • 补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储
  • 在不断的添加过程中,会涉及到扩容问题,默认的扩容方式:扩容原来容量的2倍,并将原有的数据复制过来

jdk8不同之处:

  1. new HashMap() :底层没有创建一个长度为16的数组

  2. jdk8 底层数组是Node[],而非Entry[]

  3. 首次调用put()方法时,底层创建长度为16的数组

  4. jdk7底层结构只有:数组+链表 jdk8中底层结构:数组+链表+红黑树

    当数组的某一个索引位置上的元素以链表形式存在的数据个数>8 且当前数组的长度 >64时 ,

    此时索引位置上的所有数据改为使用红黑树存储

map接口常用的方法
  • put() putAll() remove() clear()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MapTest1 {
public static void main(String[] args) {
Map map = new HashMap();
//添加
map.put("A",123);
map.put("B",123);
map.put("C",123);
//修改
map.put("A",456);
System.out.println(map);
Map map1 = new HashMap();
map1.put("D",123);
map1.put("E",123);
//putAll()
map.putAll(map1);
System.out.println(map);
//remove() 移除指定的key的key-value对,并返回value
Object e = map.remove("E");
System.out.println(e);
System.out.println(map);
//清空当前所有的数据 clear()
map.clear();
System.out.println(map);
}
  • get() containsKey() containsValue() size() isEmpty()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class MapTest2 {
    public static void main(String[] args) {
    Map map = new HashMap();
    map.put("A",123);
    map.put("B",123);
    map.put("C",234);
    //get()
    System.out.println(map.get("A"));
    System.out.println(map.size());
    //以下返回布尔值
    System.out.println(map.containsKey("A"));
    System.out.println(map.containsValue(234));
    System.out.println(map.isEmpty());
    }
    }
  • keySet() values() entrySet()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class MapTest3 {
    public static void main(String[] args) {
    Map map = new HashMap();
    map.put("A",123);
    map.put("B",155);
    map.put("C",234);
    //keySet()
    Set set = map.keySet();
    Iterator iterator = set.iterator();
    while (iterator.hasNext()){
    System.out.println(iterator.next());
    }
    System.out.println("===================");
    //values()
    Collection values = map.values();
    for (Object value : values) {
    System.out.println(value);
    }
    System.out.println("===================");
    //方式一:entrySet()
    Set entrySet = map.entrySet();
    Iterator iterator1 = entrySet.iterator();
    while (iterator1.hasNext()){
    Object next = iterator1.next();
    Map.Entry entry = (Map.Entry) next;
    System.out.println(entry.getKey()+"---->"+entry.getValue());
    }
    System.out.println("===================");
    //方式二:拼凑
    Set set1 = map.keySet();
    Iterator iterator2 = set.iterator();
    while (iterator2.hasNext()){
    Object next = iterator2.next();
    Object o = map.get(next);
    System.out.println(next+"==="+o);
    }
    }
    }
TreeMap
  • 向TreeMap中添加key-value,要求key必须是有同一个类创建的对象
  • 因为要按照key进行排序:自然排序、定制排序
  • 类似于TreeSet
properties
  • 主文件中建立jdbc.properties

    1
    2
    name=tom
    password=123456
  • 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class PropertiesTest {
    public static void main(String[] args) throws Exception {
    Properties properties = new Properties();
    FileInputStream file = new FileInputStream("jdbc.properties");
    properties.load(file);//加载流对应得文件
    System.out.println(properties.getProperty("name"));
    System.out.println(properties.getProperty("password"));

    }
    }
collections
  • collections:操作collection、map的工具类

  • reverse() shuffle() sort() swap(List,int,int)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class CollectionsTest {
    public static void main(String[] args) {
    List list = new ArrayList();
    list.add("13");
    list.add("8");
    list.add("99");
    list.add("88");
    list.add("100");
    System.out.println(list);
    //反转 reverse()
    Collections.reverse(list);
    System.out.println(list);
    //随机 shuffle()
    Collections.shuffle(list);
    System.out.println(list);
    //升序 sort()
    Collections.sort(list);
    System.out.println(list);
    //swap(List,int,int) 指定集合index位置交换
    Collections.swap(list,1,2);
    System.out.println(list);

    }
    }
  • copy()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class CollectionsTest1 {
    public static void main(String[] args) {
    List list = new ArrayList();
    list.add("13");
    list.add("8");
    list.add("99");
    list.add("88");
    list.add("100");
    List dest = Arrays.asList(new Object[list.size()]);
    System.out.println(dest.size());
    Collections.copy(dest,list);
    System.out.println(dest);
    }
    }

7.泛型

  • 使用泛型可以保证数据的安全,避免了不同类型同时出现
  • 使用泛型避免了强转操作
在集合中使用泛型
  • List中使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class GenericTest {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(56);
    list.add(44);
    list.add(22);
    list.add(55);
    for (Integer integer : list) {
    int score = integer;
    System.out.println(score);
    }
    System.out.println("=========");
    Iterator<Integer> iterator = list.iterator();
    while (iterator.hasNext()){
    System.out.println(iterator.next());
    }
    }
  • Map中使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class GenericTest1 {
    public static void main(String[] args) {
    HashMap<String, Integer> map = new HashMap<>();
    map.put("AA",80);
    map.put("BB",58);
    map.put("CC",66);
    map.put("DD",90);
    //泛型的嵌套
    Set<Map.Entry<String, Integer>> set = map.entrySet();
    Iterator<Map.Entry<String, Integer>> iterator = set.iterator();
    while (iterator.hasNext()){
    Map.Entry<String, Integer> next = iterator.next();
    String key = next.getKey();
    Integer value = next.getValue();
    System.out.println(key+"====="+value);
    }
    }
    }

总结

  1. 在实例化集合类时,可以指明具体的泛型类型
  2. 泛型的类型必须是类,不能是基本类型。需要用到基本类型时,可以拿包装类
  3. 如果没有使用泛型的类型,默认使用类型:java.lang.Object类型
自定义泛型类和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class Order<T> {
String orderName;
int orderId;
//类的内部结构可以使用类的泛型
T orderT;

public Order() {
}



public Order(String orderName, int orderId, T orderT) {
this.orderName = orderName;
this.orderId = orderId;
this.orderT = orderT;
}

public String getOrderName() {
return orderName;
}

public void setOrderName(String orderName) {
this.orderName = orderName;
}

public int getOrderId() {
return orderId;
}

public void setOrderId(int orderId) {
this.orderId = orderId;
}

public T getOrderT() {
return orderT;
}

public void setOrderT(T orderT) {
this.orderT = orderT;
}

@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderT=" + orderT +
'}';
}
//泛型方法:在方法中出现泛型的结构,泛型参数与类的泛型参数没有任何关系
//换句话说,泛型方法所属的类是不是泛型都没有关系
//泛型方法:可以声明为静态的。原因:泛型参数是在调用方法时确定的,并非在实例化类时确定的
public <E> List<E> getGeneticList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for (E e : arr) {
list.add(e);
}
return list;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class GenericTest {
public static void main(String[] args) {
Order<String> order = new Order<>();
// order.setOrderId(123);
// order.setOrderName("张三");
// order.setOrderT("李四");
// System.out.println(order);
//测试泛型方法
Integer[] arr = new Integer[]{1,2,3,4};
//泛型方法在调用时,指明泛型参数的类型
List<Integer> list = order.getGeneticList(arr);
System.out.println(list);
}
}

8.File

file的实例

file类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class FileTest {
public static void main(String[] args) {
//相对路径:相较于某个路径下,指明的路径
//绝对路径:包含盘符在内的文件或文件夹目录的路径
//构造器1
File file1 = new File("hello.txt");//相对于当前的module
File file2 = new File("D:\\IdeaProject\\SpringBoot\\he.txt");
System.out.println(file1);
System.out.println(file2);
//构造器2
File file3 = new File("D:\\IdeaProject","\\SpringBoot");
System.out.println(file3);
//构造器3
File file4 = new File(file3,"he.txt");
System.out.println(file4);
}
}
file常用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class FileTest1 {
public static void main(String[] args) {
File file1 = new File("hello.txt");
File file2 = new File("D:\\io");
//获取绝对路径
System.out.println(file1.getAbsoluteFile());
//获取路径
System.out.println(file1.getPath());
//获取名称
System.out.println(file1.getName());
//获取上层文件目录路径
System.out.println(file1.getParent());
//获取文件长度(字节数)
System.out.println(file1.length());
//获取最后一次的修改时间
System.out.println(file1.lastModified());
System.out.println();
System.out.println(file2.getAbsoluteFile());
System.out.println(file2.getPath());
System.out.println(file2.getName());
System.out.println(file2.getParent());
System.out.println(file2.length());
System.out.println(file2.lastModified());
System.out.println();
File file3 = new File("D:\\IdeaProject");
//获取指定目录下的所有文件或者文件目录的名称数组
String[] list = file3.list();
for (String s : list) {
System.out.println(s);
}
System.out.println();
//获取指定目录下的所有文件或者文件目录的file数组
File[] files = file3.listFiles();
for (File file : files) {
System.out.println(file);
}
System.out.println();


}
}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!