JAVASE笔记总结

运算符

算术运算符

+(正号)、-(负号)、+(加)、-(减)、*(乘)、/(除)、%(取模)、++(自增)、–(自减)

赋值运算符

=、+=、-=、*=、/=、%=

比较运算符(关系运算符)

==、!=、<、>、<=、>=

逻辑运算符

&、|、^(异或)、!、&&(短路与)、||(短路或)

位运算符

位运算符是针对二进制数的每一位进行运算的符号,是专门针对数字0和1进行操作的

&(按位与)、|(按位或)、~(取反)、^(按位异或)、<<(左移)、>>(右移)、>>>(无符号右移)

运算符优先级

(大概):

算数运算符>关系运算符>逻辑运算符>赋值运算符

逻辑非>逻辑与>逻辑或

赋值<三目<逻辑<关系<算术<单目

二元运算符的运算规则

整数运算

1.如果两个操作数有一个是long,则结果也为long。

2.没有long时,结果为int。即使操作数全为short、byte,结果也是int。

浮点运算

1.如果两个操作数有一个为double,则结果为double。

2.只有两个操作数都是float,则结果才是float。

取模运算

1.其操作数可以为浮点数,一般使用整数,结果是“余数”,“余数”符号和左边操作数相同,如:7%3=1,-7%3=-1,7%-3=1。

算术运算符中++,–属于一元运算符,该类运算符只需要一个操作数。

  • ++在前(b=++a):先运算,再赋值 结果:a=a+1,b=a+1
  • ++在后(b=a++):先赋值,再运算 结果:b=a,a=a+1
  • –在前(b=–a):先运算,再赋值 结果:a=a-1,b=a-1
  • –在后(b=a–):先赋值,再运算 结果:b=a,a=a-1

例题:

//测试自增,自减与之相同
		int a = 3;
		int b = a++;//执行完毕后,b=3,先给b赋值,再自增
		System.out.println("a="+a+"\nb="+b);
		a = 3;
		b = ++a;    //执行完毕后,b=4,a先自增,再给b赋值
		System.out.println("a="+a+"\nb="+b);
		

选择结构语句

三元运算

判断条件?表达式1:表达式2

通常用于对某一个变量进行赋值,当判断条件成立时,运算结果为表达式1的值,否则结果为表达式2的值

int max = x>y?x:y;

如果x>y结果为true,则输出x,否则输出y

switch语句

遇到多值判断的时候,使用switch,当然,switch完全可以使用if-else if-else代替

	char c = 'a';
		int rand = (int)(26*Math.random());
		char c2 = (char)(c + rand);
		System.out.print(c2 + ":");
		
		switch(c2) {
		case 'a':
		case 'e':
		case 'i':
		case 'o':
		case 'u':
			System.out.println("元音字母");
			break;
		case 'y':
		case 'w':
			System.out.println("半元音字母");
			break;
		default:
			System.out.println("辅音字母");
		}


注:  /*char c = 'a';
		int rand = (int)(26*Math.random());
		char c2 = (char)(c + rand);*/

	   'a'+1==>b
       'a'+2==>c
          ...
       'a'+25==>z

循环结构语句

do…while循环

和while循环不同的是:将循环条件放在循环体后面

循环体会无条件执行一次,然后再根据循环条件决定是否继续执行

for循环

for(初始化表达式;循环条件;操作表达式){

​ 执行语句…

}

循环嵌套

使用“*”打印直角三角形

int i;
		int j;
		for (i=1;i<=6;i++) {		//控制行数	
			for (j=1;j<=i;j++) {    //控制列数
				System.out.print("*");				
			}
			System.out.print("\n");
		}

	}

跳转语句(break、continue)

break语句

  • 在switch条件语句中:用于中止某个case并跳出switch结构

  • 在循环语句中:跳出循环语句,执行后面的代码

  • 当break语句出现在嵌套循环的内层循环时,它只能跳出内层循环,如果想使用break语句跳出外层循环需添加标记:

    		//1.用while输入1-4的自然数,在值为3时跳出循环
    		int x = 1;
    		while(x<=4) {
    			System.out.println("x="+x);
    			
    			if (x == 3) {
    				break;
    			}
    			
    			x++;
    		}
    		
    		//2.控制程序只打印4行“*”(跳出外层循环需标记)
    		int i;
    		int j;
    		stamp:for (i=1;i<=6;i++) {//stamp:标记;标记外层循环			
    			for (j=1;j<=i;j++) {
    				if (i>4) {
    					break stamp; //跳出所标记的外层循环
    				}
    				System.out.print("*");				
    			}
    			System.out.print("\n");
    		}
    

continue语句

用于循环语句中,终止本次循环,执行下一次循环

continue也可以使用标记,结束本次外层循环,使用方法和break类似

//对1-100之内的奇数求和
		int sum = 0;
		for(int i=1;i<=100;i++) {
			if (i % 2 == 0) {   //i是偶数,i为偶数时不累加
				continue;      //结束本次循环,执行下一次
			}
			sum += i;
		}
		System.out.println("sum="+sum);


//打印101-150之间所有的质数(跳出外层循环需标记)
		outer:for(int i=101;i<=150;i++) {
			for(int j=2;j<i/2;j++) {
				if (i%j==0) {
					continue outer;
				}
			}
			System.out.println(i+"");

方法

形参、实参

形参:定义方法时使用;实参:调用时使用

修饰符 返回值类型 方法名([参数类型 参数名1,参数类型 参数名2]){

执行语句

...

return返回值;

}

返回值类型:用于限定方法返回值的数据类型

参数类型:用于限定调用方法时传入参数的数据类型

return的作用:1、结束方法的运行;2、返回值

”参数类型 参数名1,参数类型 参数名2“是形式参数列表,可以为空

public static void main(String[] args) {
		int area = getArea(3, 5);			//调用getArea()方法、参数为实参
		System.out.println("面积是:"+area); //15
	}
	//下面定义了求矩形面积的方法,接收两个参数,其中x为高,y为宽
	public static int getArea(int x,int y) {参数为形参
		int temp = x*y;
		return temp;
	}

实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配

方法的重载(overload)

独立的、完全不同的方法,只是名称相同而已

构成重载的条件:

/*求和的方法*/
	public int add(int n1,int n2) {
		int sum = n1+n2;
		return sum;
	}
  1. ​ 不同的含义:形参类型、个数、顺序不同

  2. ​ 只有返回值不同,不构成方法的重载

    //编译错误:只有返回值不同,不构成方法的重载
    	public double add(int n1,int n2) {
    		int sum = n1+n2;
    		return sum;
    	}
    
  3. ​ 只有形参名称不同,不构成方法的重载

    //编译错误:只有参数名称不同,不构成方法的重载
    	public int add(int n2,int n1) {
    		double sum = n1+n2;
    		return sum;
    	}
    

方法的递归(recursion)

递归:递推、回归

1.定义递归头:递归的结束条件

2.递归体:什么时候需要调用自身方法

递归非常消耗资源,尽量不要使用

数组

定义:

int[] x=new int[100];

赋值方式:

//1.无赋值
int[] arr;           //声明变量
arr=new int[3];      //创建数组对象,结果0,0,0

//2.部分赋值
int[] arr=new int[3];//定义可以存储3个整数的数组
arr[0]=1;            //为数组第一个元素赋值1
arr[1]=2;            //为数组第二个元素赋值2,结果1,2,0

//3.数组赋值
int[] arr={1,2,3,4};  //直接赋值,结果1,2,3,4
int[] arr=new int[]{1,2,3,4} //建议用上面的直接赋值

可以通过“数组名.length”的方式来获取数组的长度(元素的个数)

每个数组的下标都有范围:0——length-1

int[] arr= {1,2,3,4};   //静态初始化
		
//每个数组的下标都有范围:0——length-1
System.out.println("数组的第一个元素是:"+arr[0]);//1
System.out.println("数组的第二个元素是:"+arr[1]);//2
System.out.println("数组的第三个元素是:"+arr[2]);//3
System.out.println("数组的第四个元素是:"+arr[3]);//4

System.out.println("数组的长度是:"+arr.length);//4

数组的遍历

	int[] arr01= {1,2,3,4,5,6,7,8,9,10};
	for(int i=0;i<arr01.length;i++) {
		System.out.print(arr01[i]);
	}

增强for循环

**for-each(JDK1.5新增功能):**专门用于读取数组或集合中的所有元素

public class TestArray_foreach {
	public static void main(String[] args) {
		int[] a = {3,5,9,6,7};
		//for-each循环:用于读取数组元素的值,不能修改元素的值
		for(int m:a) {
			System.out.println(m);
		}
	}
}

数组的最值

/**定义一个求数组最大值的方法*/
static int getMax(int[] arr02) {
		int max = arr02[0];//定义数组arr02的第一个元素为最大值
		for(int x=1;x<arr02.length;x++) {
			if (arr02[x]>max) {
				max = arr02[x];
			}
		}
		return max;
	}
public static void main(String[] args) {
		/**调用求数组最大值的方法*/
		int[] arr02= {4,1,3,9};
		int max = getMax(arr02);
		System.out.println("最大值:"+max);
	}

数组的排序(冒泡排序法)

/**
 * 测试冒泡法及其优化
 * @author 李宇辉
 *
 */
public class TestBubbleSort {
	public static void main(String[] args) {
		int[] values = {9,8,6,4,3,5,6,0,1};
		for(int i=0;i<values.length-1;i++) {
			boolean flag = true;
			for(int j=0;j<values.length-1-i;j++) {
				if (values[j]>values[j+1]) {
					int temp = values[j];
					values[j] = values[j+1];
					values[j+1] = temp;
					flag=false;
				}
				System.out.println(Arrays.toString(values));
			}
			if (flag) {
				System.out.println("循环结束!!!");
				break;
			}
			System.out.println("本轮循环结束");
		}
	}
}



/**
 * 冒泡法
 */
public static void main(String[] args) {
	int[] arr={5,7,9,8,6,2,4};
	System.out.println("冒泡排序前:");
	printArray(arr);  //打印数组元素
	bubbleSort(arr);  //调用排序方法
		
	System.out.println("冒泡排序后:");
	printArray(arr);  //打印数组元素
}

/**定义一个打印数组的方法*/
public static void printArray(int[] arr) {
	//遍历
	for(int i=0;i<arr.length;i++) {
		System.out.print(arr[i]+" ");
	}
	System.out.print("\n");
}
	
/**定义数组排序的方法*/
public static void bubbleSort(int[] arr) {
	//外层循环
	for(int i=0;i<arr.length-1;i++) {
		//内层循环
		for(int j=0;j<arr.length-i-1;j++) {
			if (arr[j]>arr[j+1]) {//相邻对比
				int a=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=a;
			}
		}
		System.err.println("第"+(i+1)+"轮排序后:");
		printArray(arr);//每轮比较结束后打印数组元素
	}
}

二分法查找(前提:排过序的数组)

/**二分法查找(折半索引)*/
public class TestBinarySearch {
	public static void main(String[] args) {
		int arr[] = {20,15,36,45,99,77,35,66,54,100,22,7,97};
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));
		/**下方()里面第二个是要查找的元素*/
		System.out.println(myBinarySearch(arr,35));
	}
	public static int myBinarySearch(int[] arr,int value) {
		int low = 0;              //定义最左端的元素
		int high = arr.length-1;  //定义最右端的元素
		while(low<=high) {
			int mid=(low+high)/2; //定义一个中间数
			if (value==arr[mid]) {
				return mid;
			}else if (value<arr[mid]) {
				high = mid-1;     //中间数左边的元素到mid-1结束
			}
			else {
				low = mid+1;      //中间数右边的元素从mid+1开始
			}
		}
		return -1;                //没有找到该元素
	}
}

多维数组

//第一种
int[][] arr=new int[3][4];  //3*4的二维数组
//第二种
int[][] arr=new int[3][];  //每个元素长度不确定
//第三种
int[][] arr={{1,2},{3,4,5,6},{7,8,9}};//包含三个数组

面向对象(object)

面向对象的特征

封装、继承、多态

面向对象和面向过程的总结

  1. 都是解决问题的思维方式,都是代码组织的方式
  2. 解决简单问题可以使用面向过程
  3. 解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程

类和对象

类:class

对象:object,instance(实例)

类是对象的抽象,用于描述一组对象的共同特征和行为

对象是类的实例

• 定义类(类的组成)

  • 属性 field
  • 方法 method
  • 构造方法 construtor
  • 其他:代码块 静态代码块 内部类

成员变量

定义在类中的变量称为成员变量

局部变量

定义在方法内部的变量称为局部变量

• 创建对象

  • 类名 对象名 = new 类名();
  • Person p1=new Person();

• 调用类的属性和方法

  • 对象名.成员变量
  • 对象名.成员方法

一个java程序可以有多个类,但只能有一个public修饰的类

public class Stu {  //学生类
	//属性fields
	int id;
	int age;
	String name;
	Computer comp; //计算机
	//方法
	void study() {
		System.out.println("我在认真学习"+"使用:"+comp.brand+"学java");
	}	
	void play() {
		System.out.println("打游戏");
	}
	//构造方法,用于创建这个类的对象,无参的构造方法可以由系统自动创建
	Stu(){	
	}	
	public static void main(String[] args) {
		Stu stu = new Stu();     //创建一个对象
		stu.id = 138439;
		stu.age = 22;
		stu.name = "李宇辉";	
		Computer c1 = new Computer();
		c1.brand = "惠普";
		stu.comp = c1;	
		stu.play();
		stu.study();
	}
}
class Computer{
	String brand;
}

内存分析

java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area

• 栈

  • 存放:局部变量
  • 先进后出,自下而上存储
  • 方法执行完毕,自动释放空间

• 堆

  • 存放new出来的对象
  • 需要垃圾回收器来回收

• 方法区

​ 存放永远不变或唯一的内容:类的信息(代码)、 static变量、字符串常量等.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qwjGslm-1597227817631)(D:\workspace\Test\src\com\lyh\the_third_chapter\Stu.java.png)]

构造器/构造方法(constructor)

构造器,又叫构造方法,用于对象的初始化

要点

  1. 通过new关键字调用(创建对象时)
  2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值
  3. 如果没有定义构造器,则编译器会自动定义一个无参的构造函数;如果已定义则编译器不会自动添加
  4. 构造器的方法名必须和类名一致
/*定义一个“点”(Point)类用来表示二维空间中的点(有二个坐标)。要求如下: 
	• 可以生成具有特定坐标的点对象。 
	• 提供可以设置二个坐标的方法。 
	• 提供可以计算该“点”距另外点距离的方法。
*/
class Point{
	double x,y;	
	//构造器的方法名必须和类名一致
	public Point(double _x,double _y) {
		x = _x;
		y = _y;
	}	
	public double getDistance(Point p) { //测量距离s
		return Math.sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));//两点间距离公式:根号下(x2-x1)的平方+(y2-y1)的平方
	}
}
public class TestConstructor {
	public static void main(String[] args) {
		Point p = new Point(3.0, 4.0);
		Point origin = new Point(0.0, 0.0);//原点:origin
		System.out.println(p.getDistance(origin));
	}
}

构造方法的重载

与方法重载相同

public class User {
	int id;     //id
	String name;//账户名
	String pwd; //密码
	public User() {	
	}
	public User(int id,String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public User(int id,String name,String pwd) {
		this.id = id;
		this.name = name;
		this.pwd = pwd;
	}
	public static void main(String[] args) {
		User u1 = new User();
		User u2 = new User(101,"李宇辉");
		User u3 = new User(100,"李宇飞","123456");
	}
}

垃圾回收机制(Garbage Collection)

  1. 发现无用的对象
  2. 回收无用的对象占用的空间

垃圾回收相关算法:

  1. 引用计数法
  2. 引用可达法(根搜索算法)

开发中容易造成内存泄露的操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rsEj4RiL-1597227817638)(D:\workspace\Test\src\com\lyh\the_third_chapter\开发中容易造成内存泄露的操作.png)]

this关键字

this的本质就是”创建好的对象的地址“,由于在构造方法调用前,对象已经创建,因此,在构造方法中也可以使用this代表”当前对象“

this的常用方法:

  1. 在程序中产生二义性处,应使用this来指明当前的对象。普通方法中,this总是指向调用该方法的对象;构造方法中,this总是指向正要初始化的对象
  2. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句
  3. this不能用于static方法中

static关键字

可以使用static关键字来修饰的成员变量成为静态变量,静态变量被所有实例所共享。可以使用**“类名.变量名”**的形式来访问。

注:只能用于修饰成员变量,不能用于修饰局部变量

不能调用非静态成员

public class User02 {
	int id;     //id
	String name;//账户名
	String pwd; //密码
	static String company = "李氏集团";
	public User02(int id,String name) {
		this.id=id;
		this.name=name;
	}
	public void login() {
		System.out.println("登录:"+name);
	}
	public static void printCompany() {
		//login();//调用非静态成员,编译会报错
		System.out.println(company);
	}
	public static void main(String[] args) {
		User02 u = new User02(101,"李宇辉");
		User02.printCompany();
		User02.company="西安李氏";
		User02.printCompany();
	}

}

静态代码块

当类被加载时,静态代码块会执行,由于类只加载一次,因此静态代码块也只执行一次。

静态代码块执行顺序:

  1. 上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们类的静态初始化块为止。
  2. 构造方法执行顺序和上面顺序一样。

单例模式

单例模式是指在设计一个类时,需要保证在整个程序运行期间针对该类只存在一个实例对象

public class TestSingle {//测试单例模式
	public static void main(String[] args) {
		Single s1 = Single.getInstance();
		Single s2 = Single.getInstance();
		System.out.println(s1 == s2);
	}
}
class Single{//单例
	private static Single INSTANCE = new Single();   //创建一个对象
	private Single() {                               //私有构造方法
		
	}
	public static Single getInstance() {             //提供返回该对象的静态方法
		return INSTANCE;
	}
}

内部类

成员内部类

一个类中除了可以定义成员变量、成员方法、还可以定义类,这样的类被称为成员内部类

在成员内部类中可以访问外部类的所有成员:

public class InnerMember {
	public static void main(String[] args) {
		Outer outer = new Outer();//创建外部类对象
		outer.test();             //调用test方法
	}
}
class Outer{               //定义外部类
	private int num=4;     //定义外部类的成员变量
	/**下面的代码定义了一个成员方法,方法中访问内部类*/
	public void test() {
		Inner inner = new Inner();
		inner.show();
	}	
	class Inner{           //定义内部类
		void show() {
			System.out.println("num="+num);//在成员内部类的方法中访问外部类的变量num
		}
	}
}

通过外部类访问内部类:

外部类名.内部类名 变量名=new 外部类名().内部类名();
public class TestOuter{  //接上一例题
    public static void main(String[] args){
        Outer.Inner inner = new Outer().Inner(); //创建内部类对象
        inner.show();                            //调用show()方法
    }
}

静态内部类

用static修饰的类,可以在不创建外部类对象的情况下被实例化

外部类名。内部类名 变量名=new 外部类名.内部类名();
public class InnerStatic {
	public static void main(String[] args) {
		Outer02.Inner02 inner02 = new Outer02.Inner02();//创建内部类对象
		inner02.show();//调用内部类方法
	}
}
class Outer02{
	private static int num=6;
	/**下面的代码定义了一个静态内部类*/
	static class Inner02{
		void show() {
			System.out.println("num="+num);
		}
	}
}

方法内部类

在成员方法中定义的类,只能在当前方法中被使用

public class InnerMethod {
	public static void main(String[] args) {
		Outer03 ou = new Outer03();
		ou.test();
	}
}
class Outer03{
	private int num =10;
	/**下面是在方法中定义的内部类*/
	void test() {
		class Inner03{
			void show() {
				System.out.println("num="+num);
			}
		}
		Inner03 in = new Inner03();
		in.show();
	}
}

import

package com.lyh.the_third_chapter;
import com.lyh.test.Constant;
public class TestImport {
	public static void main(String[] args) {
//		com.lyh.test.Constant c = new com.lyh.test.Constant();//这样子写特别繁琐
		Constant c = new Constant();
	}
}


//注:Constant在com.lyh.test包下

静态导入(JDK1.5新功能)

import static java.lang.Math.*;     //导入Math下的静态属性
public class TestStaticImport {
	public static void main(String[] args) {
		System.out.println(Math.PI); //静态导入前
		
		System.out.println(PI);      //静态导入后
	}
}

继承

  • 父类也称为派生类、超类、基类等
  • java中只有单继承,接口有多继承
  • 子类继承父类,可以得到父类的全部属性和方法(构造方法除外),但不见得可以直接访问(如:父类私有的属性和方法)
  • 如果定义一个类时,没有调用extands,则它的父类是:java.lang.Object

eclipse中可以使用crtl+t查看类的继承结构

instanceof运算符

instanceof是二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建的对象时,返回true,否则false,如:

public class Test{
    public static void main(String[] args){
        Student s = new Student("罗小黑",155,“java);
        System.out.println(s instanceof Person); //true
        System.out.println(s instanceof Student);//true
    }
}

方法的重写(override)

子类通过重写父类的方法,可以用自身的行为替换父类的行为

重写的三个要点:

  1. ”==“:方法名、形参列表相同
  2. “<=”:返回值类型和声明异常类型,子类小于等于父类
  3. “>=”:访问权限,子类大于等于父类

封装

  • 提高代码安全性
  • 提高代码的复用性
  • “高内聚”:封装细节,便于修改内部代码,提高可维护性
  • “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作

访问控制符

private:表示私有,只有自己类能访问

default:表示没有修饰符修饰,只有同一个包的类能访问

protected:表示可以被同一个包中的类以及其他包的子类访问

public:表示可以被该项目中的所有包中的类访问

修饰符 同一个类 同一个包中 子类(不同包) 所有类
private *
default * *
protected * * *
public * * * *

封装使用细节

  • 一般使用private访问权限
  • 提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是以is开头
  • 一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法使用public修饰

多态

  1. 多态是方法的多态,不是属性的多态(与属性无关)
  2. 多态的存在要有3个必要条件:继承、方法重写、父类引用指向子类对象(向上转型)
  3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法时,此时多态就出现了
public class TestPolym {
	public static void main(String[] args) {
		Animal a = new Animal();
		animalCry(a);        //输出:	叫了一声
		
//		Dog dog = new Dog();
        Animal dog = new Dog();   /**自动向上转型*/
		animalCry(dog);      //输出:汪汪汪,叫了三声
		
        Dog d2 = (Dog)dog;        /**强制向下转型*/
		d2.seeDoor();
        
		animalCry(new Cat());//输出:喵喵,叫了两声
	}
	
	static void animalCry(Animal a) {
		a.shout();
	}
}
class Animal{
	public void shout() {
		System.out.println("叫了一声");
	}
}
class Dog extends Animal{
	public void shout() {
		System.out.println("汪汪汪,叫了三声");
	}
	public void seeDoor() {
		System.out.println("看门!");
	}
}
class Cat extends Animal{
	public void shout() {
		System.out.println("喵喵,叫了两声");
	}
}

final关键字

  1. 修饰变量:被它修饰的变量不可变(常量)。一旦赋了初值,就不能重新赋值

    final int MAX_SPEED = 120;
    
  2. 修饰方法:该方法不可被子类重写,但是可以被重载

    final void study(){}
    
  3. 修饰类:修饰的类不能被继承。比如:Math、Sting等。

    final class A{}
    

抽象类

  1. 抽象类不能被实例化
  2. 如果有一个类有抽象方法,那么这个类称为抽象类
  3. 继承抽象类的子类必须对抽象类的方法做实现

抽象方法

  1. 不包含方法体的方法称为抽象方法,必须使用abstract关键字来修饰,使用abstract修饰的类称为抽象类;
  2. 包含抽象方法的类一定是抽象类,但抽象类可以不包含任何抽象方法;
  3. 抽象类不可以被实例化;
  4. 若想要实现抽象类中定义的方法,需要创建一个子类,在子类中将抽象类中的抽象方法进行实例
abstract class TestAbstract{
	public static void main(String[] args) {
		Dog02 dog = new Dog02();     //创建Dog02类的实例对象
		dog.shout();                 //调用dog对象的shout()方法
	}
}
abstract class Animal02{            //定义抽象类Animal02
    abstract void shout();          //定义抽象方法shout()
}
class Dog02 extends Animal02{       //定义Dog02继承抽象类Animal02
	void shout() {                   //实现抽象方法shout()
		System.out.println("汪汪。。。");
	}
}

接口(interface)

  • 接口中定义的方法默认用“public abstract”来修饰,即抽象方法
  • 接口中的变量默认用“public static final”来修饰,即全局常量

接口用implenment实现:

public class TestInterface {
	public static void main(String[] args) {
	/*	Volant volant = new Angle();
		volant.fly();
		Honest honest = new GoodMan();
		honest.helpOther();*/
		Angle angle = new Angle();
		angle.fly();
		angle.helpOther();
		GoodMan goodMan = new GoodMan();
		goodMan.helpOther();
		BirdMan birdMan = new BirdMan();
		birdMan.fly();
	}
}
/**
 * 飞行接口
 * @author 李宇辉
 *
 */
interface Volant{
	int FLY_HEIGHT = 1000;
	void fly();
}
//善良接口
interface Honest{
	void helpOther();
}
class Angle implements Volant,Honest{//实现类可以实现多个父接口
	@Override
	public void fly() {
		System.out.println("Angle.Fly()");
	}
	@Override
	public void helpOther() {
		System.out.println("Angle.helpOther()");
	}
}
class GoodMan implements Honest{
	public void helpOther() {
		System.out.println("GoodMan.helpOther()");
	}
}
class BirdMan implements Volant{
	public void fly() {
		System.out.println("BirdMan.Fly()");
	}
}

异常

数组越界异常:ArryIndexOutOfBoundsException
空指针异常:NullPointerException
类型转换异常:ClassCastException
不能加载所需的类:ClassNotFoundException
欲得到数据类型与实际输入类型不匹配:InputMismatchException
方法接收到非法参数:IllegalArgumentExceptio
数字格式转换异常,如把"ab"转换成数字:NumberFormatException
算术错误情形(如以零作除数):ArithmeticException

try-catch处理异常

public class Test01 {
	public static void main(String[] args) {
		readMyFile();
	}
	public static void readMyFile() {
		FileReader reader = null;
		try {
			reader = new FileReader("D:/JAVA基础视频/java300/06_异常机制/测试文档.txt");
			System.out.println("1");
			char c1 = (char)reader.read();
			System.out.println(c1);
			
		} catch (FileNotFoundException e) {//子类异常要在父类异常前面
			System.out.println("2");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			System.out.println("3");
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

throws声明异常(谁调给谁抛)

public class Test02 {
	public static void main(String[] args) throws IOException {
		readMyFile();
	}
	public static void readMyFile() throws IOException {
		FileReader reader = null;
		reader = new FileReader("D:/测试文档.txt");
		System.out.println("1");
		char c1 = (char)reader.read();
		System.out.println(c1);
		if (reader!=null) {
			reader.close();
		}
	}
}

容器(集合类)

泛型

泛型的本质就是“数据类型的参数化”。

可以把“泛型”理解为数据类型的一个占位符(形参),即告诉编译器,在调用泛型时必须传入实际类型。

public class TestGeneric {
	public static void main(String[] args) {		
		MyCollection<String> mc = new MyCollection<String>();
		mc.set("罗小黑战记", 0);
		mc.set("某某某战机", 1);
		String a = mc.get(0);
	}
}
class MyCollection<E>{
	Object[] o = new Object[5];
	public void set(E e,int index) {//设置内容,索引
		o[index] = e;
	}
	public E get(int index) {       //获取索引
		return (E)o[index];
	}
}

List

有序、可重复的集合

List接口常用的实现类:ArrayList(数组)、LinkedList(链表)、Vector

数组:占用空间连续,寻址容易,查询速度快,但是增删效率低

链表:占用空间不连续,寻址困难,查询速度慢,但是增删效率高

Set

无序、不可重复

HashSet、TreeSet等

List的方法(Collection的方法)

/**
 * 测试Collection接口中的方法
 * @author 李宇辉
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class TestList {
	public static void main(String[] args) {	
		test01();
		test02();
	}
	public static void test01() {
		Collection<String> c = new ArrayList<String>();
		System.out.println(c.size());//该方法用于判断集合长度
		System.out.println(c.isEmpty());//该方法用于判断是否为空
		c.add("罗小黑");
		c.add("罗小白");
		System.out.println(c);
		System.out.println(c.size());
		System.out.println(c.contains("洛伊"));//该方法用于判断这个元素是否包含在此集合中
		
		Object[] object = c.toArray();//该方法用于转换为Object数组
		System.out.println(object);
		
		c.remove("罗小白");//该方法仅用于移除集合内的地址,对象仍然存在
		System.out.println(c);
		c.clear();//该方法用于清空集合
		System.out.println(c.size());
	}
	
	public static void test02() {
		List<String> list01 = new ArrayList<String>();
		list01.add("aa");
		list01.add("bb");
		list01.add("cc");
		List<String> list02 = new ArrayList<String>();
		list02.add("aa");
		list02.add("dd");
		list02.add("ee");
		
		System.out.println("list01:"+list01);
//		list01.addAll(list02);//该方法用于将另一个集合的所有元素加进来
//		list01.removeAll(list02);//该方法用于删除两个集合中相同的元素
		list01.retainAll(list02);//该方法用于删除两个集合中不相同的元素(保留交集)
		System.out.println("list01:"+list01);
		System.out.println(list01.containsAll(list02));//该方法用于判断是否包含另一个集合的所有元素		
	}
}

索引位置的方法

public static void test03() {
	List<String> list = new ArrayList<>();
	list.add("A");
	list.add("B");
	list.add("C");
	list.add("D");
	System.out.println(list);
	list.add(2, "张三");//在索引为2处添加一个元素:张三
	System.out.println(list);
	list.remove(2);//移除索引为2处的元素
	System.out.println(list);
	list.set(2, "李四");//在索引为2处设置(修改)元素为:李四
	System.out.println(list);
	System.out.println(list.get(2));//获取索引为2处的元素		
	list.add("C");
	list.add("B");
	list.add("A");
	System.out.println(list);		
	System.out.println(list.indexOf("B"));//indexOf返回指定元素第一次出现的位置,没有则返回-1
  System.out.println(list.lastIndexOf("B"));//lastIndexOf返回指定元素最后一次出现的位置,没有则返回-1	
}

Map

Map就是用来存储"键(key)值(value)对 "的,Map类中的"键值对"通过来标识,所以"键对象"不能重复

Map接口的实现类有HashMap、TreeMap、HashTable、Propertise等

HashMap与HashTable的区别:

HashMap:线程不安全,效率高,允许key或value为空

HashTable:线程安全,效率低,不允许key或value为空

Map接口中常用的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPrOVHdm-1597227817649)(D:\JAVA基础视频\java300\07_容器和数据结构\资料\Map接口中常用的方法.png)]

public class TestMap {
	public static void main(String[] args) {
		Map<Integer,String> m1 = new HashMap<Integer, String>();
		m1.put(1, "one");
		m1.put(2, "two");
		m1.put(3, "three");
		
		System.out.println(m1.get(1));
		
		System.out.println(m1.size());//长度
		System.out.println(m1.isEmpty());//是否为空
		System.out.println(m1.containsKey(2));//是否包含键2
		System.out.println(m1.containsValue("four"));//是否包含值"four"
		
		Map<Integer,String> m2 = new HashMap<>();
		m2.put(4, "四");
		m2.put(5, "五");
		
		m1.putAll(m2);
		System.out.println(m1);
		
		//Map中键不能重复如果重复(是否重复是根据equals方法),则新的覆盖旧的
		m1.put(3, "三");
		System.out.println(m1);
	}
}

迭代器(Iterator)

迭代器一般写在for循环中

迭代器遍历List:

public class TestIterator {
	public static void main(String[] args) {
		testIteratorList();
	}
	
	public static void testIteratorList() {
		List<String> list = new ArrayList<>();
		list.add("aa");
		list.add("bb");
		list.add("cc");	
		/**使用Iterator遍历List*/
		for(Iterator<String> it = list.iterator();it.hasNext();) {//获得迭代器。list.iterator()相当于初始化
			String temp = it.next();
			System.out.println(temp);
		}
	}
}

迭代器遍历Set:

public class TestIterator {
	public static void main(String[] args) {
		testIteratorSet();
	}
	public static void testIteratorSet() {
		Set<String> set = new HashSet<>();
		set.add("aa");
		set.add("bb");
		set.add("cc");	
		/**使用Iterator遍历Set*/
		for(Iterator<String> it2 = set.iterator();it2.hasNext();) {//获得迭代器,list.iterator()相当于初始化
			String temp = it2.next();
			System.out.println(temp);
		}
	}
}

迭代器遍历Map:

public class TestIterator {
	public static void main(String[] args) {
		testIteratorMap();
	}
	public static void testIteratorMap() {
		Map<Integer, String> map1 = new 		HashMap<Integer, String>();
		map1.put(100,"aa");
		map1.put(200,"bb");
		map1.put(300,"cc");
		/**使用Iterator遍历Map*/
		//第一种遍历Map的方式
		Set<Entry<Integer, String>> ss = map1.entrySet();
		for(Iterator<Entry<Integer, String>> iter = ss.iterator();iter.hasNext();) {//获取迭代器
			Entry<Integer, String> temp = iter.next();
			System.out.println(temp.getKey()+"---"+temp.getValue());
		}	
		//第二种遍历Map的方式
		Set<Integer> keySet = map1.keySet();
		for(Iterator<Integer> iter=keySet.iterator();iter.hasNext();) {
			Integer key = iter.next();
			System.out.println(key+"---"+map1.get(key));
		}
	}
}

遍历各种集合的方法汇总

遍历List的方法汇总:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rd477aNx-1597227817654)(D:\JAVA基础视频\java300\07_容器和数据结构\资料\遍历List的方法汇总.png)]

遍历Set的方法汇总:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L63giWAi-1597227817655)(D:\JAVA基础视频\java300\07_容器和数据结构\资料\遍历Set的方法汇总.png)]

遍历Map的方法汇总:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qfLV23s-1597227817656)(D:\JAVA基础视频\java300\07_容器和数据结构\资料\遍历Map的方法汇总.png)]

Collections工具类

Collection是接口,Collections是工具类

public class TestCollections {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		for(int i=0;i<10;i++) {
			list.add("李:"+i);
		}
		System.out.println(list);
		
		Collections.shuffle(list);//随机排列list中的元素
		System.out.println(list);
		
		Collections.reverse(list);//逆序排列
		System.out.println(list);
		
		Collections.sort(list);   //按照递增的方式排序,自定义的类使用:Collection接口
		System.out.println(list);
		
		System.out.println(Collections.binarySearch(list, "李:3"));//二分法查找(折半查找)
	}
}

多线程

程序、进程、线程

在操作系统中运行中的程序就是进程,如看视频

一个进程可以有多个线程,如视频中同时听声音、看图像、显示字幕

如何进行多线程

  • 继承Thread类

    ​ 1.重写run方法

    ​ 2.调用start方法

    package cn.lyh.thread;
    /**
     * 创建线程方式一
     * 1.创建:继承Threda类+重写run方法
     * 2.启动:创建子类对象+调用start方法
     * @author 李宇辉
     *
     */
    public class StartThread extends Thread{//继承Threda类
    	/**
    	 * 线程入口点
    	 */
    	@Override //重写run方法
    	public void run() {
    		for(int i=0;i<20;i++) {
    			System.out.println("听歌");
    		}
    	}
    	public static void main(String[] args) {
    		//创建子类对象
    		StartThread st = new StartThread();
    		//启动
    		st.start();//不保证会立即运行,由cpu调用,多线程
    		//st.run();//普通方法调用,单线程
    		for(int i=0;i<20;i++) {
    			System.out.println("写作业");
    		}
    	}
    }
    
  • 实现Runnable接口(常用)

    ​ 1.重写run方法

    ​ 2.new 一个Thread对象,调用start方法(new Thread().start())

    package cn.lyh.thread;
    /**
     * 创建线程方式二
     * 1、创建:实现Runnable+重写run
     * 2、启动: 创建实现类对象 +Thread对象+ start
     * 
     * 推荐: 避免单继承的局限性,优先使用接口
     * 方便共享资源
     * @author 李宇辉
     *
     */
    public class StartRun implements Runnable{
    	/**
    	 * 线程入口点
    	 */
    	@Override
    	public void run() {
    		for(int i=0;i<20;i++) {
    			System.out.println("一边听歌");
    		}
    	}
    	public static void main(String[] args) {			
    		/*//创建实现类对象
    		StartRun sr =new StartRun();
    		//创建代理类对象
    		Thread t =new Thread(sr);
    		//启动 
    		t.start(); //不保证立即运行 cpu调用
    */		
    		new Thread(new StartRun()).start();
    		//st.run(); //普通方法调用
    		for(int i=0;i<20;i++) {
    			System.out.println("一边coding");
    		}
    	}
    }
    
  • 实现Callable接口(juc)

线程方法

  • sleep()
    • 使线程停止运行一段时间,将处于阻塞状态
    • 如果调用了sleep方法后,没有其他等待执行的线程,这个时候当前线程不会马上恢复执行!
  • join()
    • 阻塞指定线程等到另一个线程完成以后再执继续行
  • yield()
    • 让当前正在执行的线程暂停,不是阻塞线程,而是将线程转入就绪状态
    • 调用了yield方法后,如果没有其他等待执行的线程,此时当前线程就会马上恢复执行
  • setDaemon()
    • 可以将指定的线程设置为后台线程,守护线程
    • 创建用户线程的线程结束时,后台线程也随之消亡
    • 只能在线程启动之前把它设为后台线程
  • setPriority(int newPriority) getPriority()
    • 线程的优先级代表的是概率
    • 范围从1到10,默认为5
  • stop()停止线程(不推荐使用

网络编程

InetAddress类:有多个静态方法

1、getLocalHost:本机

2、getByName:根据域名DNS|IP地址—>IP

两个成员方法:

1、getHostAddress:返回地址

2、getHostName:返回计算机名

端口

cmd命令下:

  • 查看所有端口:netstat-ano
  • 查看指定端口:netstat-ano|findstr"808"
  • 查看指定进程:tasklist|findstr"2676"(2676–>PID)
  • 查看具体程序:使用任务管理器查看PID

InetSocketAddress类

  • 该类实现了IP套接字地址(IP地址+端口号)它也可以是一对(主机名+端口号),在这种情况下,将尝试解析主机名。如果解决失败然后地址说是未解决的但仍可以使用在某些情况下,如通过代理连接。
  • 它提供了一个不可变的对象,用于绑定、连接或作为返回值的套接字使用。
  • 通配符是一种特殊的IP地址。这通常意味着“任何”只能用于bind操作。

InetSocketAddress类:父类为SocketAddress

1、构造器

​ new InetSocketAddress(地址|域名,端口);

2、方法

​ getAddress()

​ getPort()

​ getHostName()

URL

Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:

protocol、host、port、path、parameter、anchor

import java.net.MalformedURLException;
import java.net.URL;
/**
 * 测试URL
 * 1、协议
 * 2、域名、计算机
 * 3、端口:默认80
 * 4、请求资源:
 * http://www.baidu.com:80/index.html?uname=shsxt&age=18#a
 * @author 李宇辉
 */
public class TestURL {
	public static void main(String[] args)throws MalformedURLException{
	    URL url = new URL("http://www.baidu.com:80/index.html?uname=shsxt&age=18#a");
	    //获取四个值
	    System.out.println("协议:"+url.getProtocol());//"http"
	    System.out.println("域名|ip:"+url.getHost());//"www.baidu.com"
	    System.out.println("端口:"+url.getPort());//"80"
	    System.out.println("请求资源1:"+url.getFile());//"/index.html?uname=shsxt&age=18"
	    System.out.println("请求资源2:"+url.getPath());//"/index.html"

	    //参数
	    System.out.println("参数:"+url.getQuery());//"uname=shsxt&age=18"
	    //锚点
	    System.out.println("锚点:"+url.getRef());//"a"
	}
}

Web Spider(爬虫)

/**
 * 测试爬虫
 * @author 李宇辉
 *
 */
public class TestWebSpider {
	public static void main(String[] args) throws Exception {
		//获取URL
		URL url = new URL("https://www.jd.com");
		//下载资源
		InputStream is = url.openStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
		String msg=null;
		while(null!=(msg=br.readLine())) {
			System.out.println(msg);
		}
		br.close();
		//分析
		//处理
	}
}

接字使用。

  • 通配符是一种特殊的IP地址。这通常意味着“任何”只能用于bind操作。

InetSocketAddress类:父类为SocketAddress

1、构造器

​ new InetSocketAddress(地址|域名,端口);

2、方法

​ getAddress()

​ getPort()

​ getHostName()

URL

Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:

protocol、host、port、path、parameter、anchor

import java.net.MalformedURLException;
import java.net.URL;
/**
 * 测试URL
 * 1、协议
 * 2、域名、计算机
 * 3、端口:默认80
 * 4、请求资源:
 * http://www.baidu.com:80/index.html?uname=shsxt&age=18#a
 * @author 李宇辉
 */
public class TestURL {
	public static void main(String[] args)throws MalformedURLException{
	    URL url = new URL("http://www.baidu.com:80/index.html?uname=shsxt&age=18#a");
	    //获取四个值
	    System.out.println("协议:"+url.getProtocol());//"http"
	    System.out.println("域名|ip:"+url.getHost());//"www.baidu.com"
	    System.out.println("端口:"+url.getPort());//"80"
	    System.out.println("请求资源1:"+url.getFile());//"/index.html?uname=shsxt&age=18"
	    System.out.println("请求资源2:"+url.getPath());//"/index.html"

	    //参数
	    System.out.println("参数:"+url.getQuery());//"uname=shsxt&age=18"
	    //锚点
	    System.out.println("锚点:"+url.getRef());//"a"
	}
}

Web Spider(爬虫)

/**
 * 测试爬虫
 * @author 李宇辉
 *
 */
public class TestWebSpider {
	public static void main(String[] args) throws Exception {
		//获取URL
		URL url = new URL("https://www.jd.com");
		//下载资源
		InputStream is = url.openStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
		String msg=null;
		while(null!=(msg=br.readLine())) {
			System.out.println(msg);
		}
		br.close();
		//分析
		//处理
	}
}

你可能感兴趣的:(笔记,java)