Java-基础学习笔记

01.基础知识

java基础知识

Java的跨平台是由虚拟机来实现的。

JVM:java虚拟机

JRE:java运行环境(包括java虚拟机和java所需要的核心类库)

JDK:Java开发工具包(包含java开发工具,包含JRE)

jdk编写的程序交由jre运行,由jvm保证跨平台性。

//不适用eclip的方式
//先按照java符合的规则编写.java文件
//然后使用javac 文件名    来生成.class文件(编译成二进制数据文件的过程)
//然后使用java 文件名(没有后缀)    运行class文件(电脑解析二进制命令来执行操作。)

常用的DOS命令

切换盘符: D:

查看当前目录下的目录文件: dir

切换目录 cd

清屏 cls

退出exit

HelloWorld案例

java和javac只能在bin目录下执行。所以文件需要放到bin目录下进行执行。目前需要的东西和c#相同

java中的打印语句是System.out.println();

java文件是先有javac把源文件编译成字节码文件,然后由java编译成二进制文件进行执行

java文件中区分大小写。class单词是全小写的。

注释

/**/多行注释

//单行注释

常量

/*
常量在程序执行过程中其值不可以发生改变的量叫做常量。
	常量分类:
		字符串常量  "Helloworld"
		正数常量	123213
		小数常量	1.2
		字符常量    'a'
		布尔常量  	true,false
		空常量		null
		
*/
public class HelloWorld{
	public static void main(String[] args) {
		System.out.println("HelloWorld");
	}
}

变量

变量未赋值不能使用

变量只在所属的范围内有效

​ 局部变量

​ 全局变量

​ 变量的范围是在他所在的大括号里面都有效

代码块也可以用不报错。。。。nb

{

​ int a = 12;

}

###数据类型

计算机存储的最小单元叫做字节。byte

最小信息单元叫做为bit

一个字节由8bit组成

标识符

标识符用来给包,类,变量等起名字的符号。
组成规则
	unicode字符组成
		数字字符,英文大小写字母,汉字
	下划线
		_
	美元符号
		$
注意:
	数字不能开头
	不能是关键字

	常见命名规则:
		基本规则
			见名知意
		常见命名规则:
			包(文件夹,用于对类进行管理)
				组成包的单词全部小写
				多级包.隔开
				com.haha.fuck.dadadadada
			类的命名规则
				一个单词首字母大写
					Studnet
				多个单词每个单词首字母大写
					HelloWorld
			方法和变量命名:
				一个单词
					首字母小写
				多个单词
					从第二个单词开始每个单词的首字母大写

类型转换

隐式转换:int c = a+b;

强制转换:byte d=(byte)(a+b);

Eclipse的常用快捷键

行注释/取消行注释:ctrl+/

块注释/取消块注释:Ctrl+Shift+/ Ctrl+Shift+\

代码补全快捷键:**alt+/,**调出选项,上下方向键选择,然后点击回车

代码导包的快捷键:ctrl + shift + o,组织导入,能帮你一次去掉所有未使用的Import声明。

编写代码时将代码窗口大屏显示,提高工作效率:ctrl+m

查看某个类中的方法使用这个此快捷键:ctrl+o

格式化代码,快捷键能够将代码按照Java的驼峰命名规则进行显示,对代码的可读性增强:ctrl+shift+F

重命名,此快捷键可以重命名属性和方法:alt+shift+r

02.运算符与表达式

Eclipse编译器

alt+/内容辅助键

注释快捷键

​ 单行注释 选中后ctrl+/ 取消选中后ctrl+/

​ 多行注释 选中 ctrl+shift+/,取消注释ctrl+shift+\

整理格式快捷键

​ ctrl+shift+f

项目的删除和导入

字符参与加法运算

字符在和int+的时候自动转换为ascii中对应的值

A:65 a:97 0:48

字符串参与加法运算,会自动把其正数小数转换成字符串相连起来。

运算时从左向右进行的,int a+int b +string会先计算相加,然后在连接字符串

++:放在前面先+1后面先赋值

–:同上

扩展的赋值运算符:隐含着强制类型转换

逻辑运算符

&,|,^,!

&& ||

&: 有false则false

|:有true则true

^:相同为false,不同为true。举例:(男女)

!:true则false,false则true

public class OperatorDemo{
  public static void main(string{} args){
    int a =3;
    int b = 4;
    int c=5;
    
    System.out.println((a>b)&(a>c))
    System.out.println((a<b)&(a>c))
    System.out.println((a>b)&(a<c))
    System.out.println((a<b)&(a<c))
    
    System.out.println((a>b)|(a>c))
    System.out.println((a<b)|(a>c))
    System.out.println((a>b)|(a<c))
    System.out.println((a<b)|(a<c))
    
    System.out.println((a>b)^(a>c))
    System.out.println((a<b)^(a>c))
    System.out.println((a>b)^(a<c))
    System.out.println((a<b)^(a<c))
    
    System.out.println((a>b))
    System.out.println(!(a>b))
	System.out.println(!!(a>b))
  }
}

&&,||

public class OperatorDemo{  
	public static void main(string{} args){    
      int a =3;    
      int b = 4;    
      int c=5;   

      System.out.println((a>b)&&(a>c))    
      System.out.println((a<b)&&(a>c))    
      System.out.println((a>b)&&(a<c))    
      System.out.println((a<b)&&(a<c)) 

      System.out.println((a>b)||(a>c))    
      System.out.println((a<b)||(a>c))    
      System.out.println((a>b)||(a<c))    
      System.out.println((a<b)||(a<c))        	//&&和&一样。另一个也一样
      //&&如果第一个为false则不执行右边&不管
      //||和|同上面差不多
      //&&和||有短路效果
	}
}

三元运算符

关系表达式?表达式1:表达式2

​ a:计算关系表达式的值看true还是false

​ b:true表达式1为结果

​ C:false表达式2为结果

int a= 10;
int b =20;
int c=null;
c=(a>b)?a:b;

键盘录入

为了提高程序的灵活性,我们需要把数据改进成为键盘录入

如何使用scanner键盘录入数据哪,记住下面步骤

使用步骤:
	导入包:
		import java.util.Scanner;//写到class上面,但是不能再package上面。在一个类中的顺序package>import>class
	创建键盘录入对象:
		Scanner sc = new Scanner(System.in);
	接收数据:
		int c = sc.nextInt();//拿到键盘中的数据。int类型的
import java.util.Scanner;

public class test{
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in)
    int c = sc.nextInt();
  }
}
package com.itheima;

import java.util.Scanner;
public class ScannerDemo {
	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		int c = sc.nextInt();
		System.out.println(c);
	}
}

03.条件判断与循环语句

流程控语句

1、顺序结构

​ 按照先后循序依次执行,程序中大多数的代码都是顺序结构的。

public class OrderDemo{
  public static void main(String[] args){
    System.out.println("1");
    System.out.println("2");
    System.out.println("3");
    System.out.println("4");
    System.out.println("5");
    System.out.println("6");
    System.out.println("7");
  }
}

2、选择结构

​ if语句

​ 第一种格式:if(表达式){语句体}

​ 第二种格式:

​ if(){}

​ else{}

​ 第三种格式:

​ if(){}

​ else if(){}

​ …

​ else{}

​ switch语句:

​ switch(表达式)

​ {

​ case 值1:语句;break;

​ case 值2:语句;break;

​ …

​ default:语句;break;

​ }

​ 值可以是:byte,short,int,char类型

​ JDK5以后可以是枚举类型

​ JDK7以后可以是字符串

3、循环结构

​ for循环

for(;;){}

​ while循环

while(){}

扩展格式

初始化语句;

while(判断条件语句){	

	循环体语句;

	控制条件语句;
}

​ do…while循环

do{}
while()

break:结束本次循环

​ 只能在循环和switch中使用

continue:跳过本次循环

04.数组

Random

导包

​ import java.util.Random

​ 创建对象

​ Random r = new Random();

​ 获取随机数

​ int number = r.nextint(10);//产生的随机数是0到9的[0,10);

//猜数字小游戏
package com.itheima_01;
import java.util.Scanner;
import java.util.Random;
public class RandomTest {
	public static void main(String[] args) {
		Random ran = new Random();
		int number = ran.nextInt(100)+1;
		System.out.println("这是一个1,100的随机数请随便猜。");
		System.out.println("请输入你猜的数据:");
		Scanner sc = new Scanner(System.in);
		int guess  = sc.nextInt();
		while(true){
			if(guess>number){
				System.out.println("大了");
				System.out.println("从新输入");
				guess =  sc.nextInt();
			}
			else if(guess <number){
				System.out.println("小了");
				System.out.println("从新输入");
				guess =  sc.nextInt();
			}
			else if(guess == number){
				System.out.println("对了");
				break;
			}
			else{
				System.out.println("错了");
				System.out.println("从新输入");
				guess =  sc.nextInt();
			}
		}
		
	}
}

数组

数组是多个变量的容器。

数组存储的是同一类型到变量

定义格式

​ int[] arr;

​ int arr[];

数组初始化:

​ A:数组初始化就是为数组开辟内存空间,,并未数组中的每个元素富裕初始值

​ B:我们有两种方式可以实现数组初始化

​ 动态初始化: 只给出初始化长度,由系统给出初始化值。

​ 静态初始化: 只给出初始化值。由系统决定长度。

动态初始化:

​ 数据类型[] 数组名= new 数据类型[数组长度]

​ 直打印数组名字会打印数组的地址名。

int[] arr = new int[3];//new开辟空间
//获取元素值用索引获取 arr[0]

java中的内存分配

堆:存储的是new出来的东西
栈:(存储的局部变量)
方法区:面向对象进阶中讲
本地方法区:和系统相关
寄存器:(给cpu使用)

静态初始化

int[] arr = new[] {1,2,3,4,5};

两个常见的小问题

数组索引超出边界。
数组不在指向堆内存。

数组长度

arr.length();//可以获取

二维数组

数据类型[][] arr;
数据类型 数组名 [][];
数据类型[] arr[];

动态初始化;
数据类型[][] 数组名 = new 数据类型[m][n];

静态初始化
数据类型[][] 数组名 = new 数据类型[][]{{1,2},{1,1},{1,2}}
数据类型[][] 数组名 ={{1,2},{1,1},{1,2}}

05.函数与方法

方法

//方法定义格式
/*
修饰符 返回值类型 方法名(数据类型 变量名,数据类型 变量名){
	代码块
	return 返回值类型变量;
}
明确两个
	返回值类型
	参数列表

三种调用方法:
	A:单独调用。没有卵用。
	B:输出调用,可以打印返回结果
	C:赋值调用,可以把返回的数据继续使用

使用void修饰的方法只能单独调用。不能输出和赋值
*/
package myMethod;

public class MyMethod {
	
	public static void main(String[] args){
      	//单独调用
      	//AddInt(20,60);
      
      	//输出调用
		//System.out.println(AddInt(20,60));
		
      	//赋值调用
      	//int s = AddInt(20;690);
      	//System.out.println(s);
      
	}
	public static int AddInt(int a,int b){
		int c = a + b;
		return c;
	}
}

方法重载

/*
方法重载就是在同一类中出现了方法名称相同的方法。
特点:
	方法名相同
	参数列表不同
		参数个数不同。参数对应的类型不一样。一个或一个以上符合就行
	返回值不影响重载,不同返回值,但是参数列表相同的也不能重载
*/
package myMethod;

public class MyMethod {
	
	public static void main(String[] args){
		System.out.println(AddInt(20,60));
		
	}
	public static int AddInt(int a,int b){
		int c = a + b;
		return c;
	}
	public static float AddInt(int a,int b){
		float c = a + b;
		return c;
	}
}
//形参和实参。形参是定义的时候参数列表中的参数。实参是调用的时候使用的实际参数。形参在基本类型的时候是不会改变实参的。如果是引类型的数据,形参是可以改变实参的。
//例如数组:


public class AegsDemo2{
  public static void main(String[] args){
    int[] arr = {1,2,3,4,5};
    for(int x=0;x<arr.length;x++){
      System.out.println(arr[x]);
    }
    change(arr);
    for(int x=0;x<arr.length;x++){
      System.out.println(arr[x]);
    }
  }
  
  public static void change(int[] arr){
    for(int x=0;x<arr.length;x++){
      if (arr[x]%2==0){
        arr[x]*=2;
      }
    }
  }
}

练习数组求和

package myMethod;

public class MyMethod {
	
	public static void main(String[] args){
		int[] arr ={1,2,3,4,5};
		int sum = sum1(arr);
		System.out.print(sum);
	}
	public static int AddInt(int a,int b){
		int c = a + b;
		return c;
	}
	public static int sum1(int[] arr){
		int s=0;
		for (int i=0;i<arr.length;i++) {
			s+=arr[i];
		}
		return s;
	}
}

06.断点调试

DeBug

断点调试作用:

​ A:查看程序的执行流程

​ B:调制程序

断点:其实就是一个标记:

添加断点的方法:

​ 在代码的左边双击即可

​ 启动的时候用debug as 启动

断点只能加在有效的语句上

case穿透

​ 找到适合的条件,执行相应的代码。如果没有break,就一直执行下面的代码不在进行判断。一直执行到break

调试错误的时候的debug程序很好玩的

07.面向对象编程

/*
 * 面向对象思想:
 * 		面向对象是基于面向过程的编程思想。
 * 
 * 		面向过程:强调的是每一个功能的步骤
 * 		面向对象:强调的是对象,然后由对象去调用功能
 * 
 * 面向对象的思想特点:
 * 		A:是一种更符合我们思考习惯的思想
 * 		B:可以将复杂的事情简单化
 * 		C:将我们从执行者变成了指挥者
 * 
 * 举例:
 * 		买电脑:
 * 			面向过程:我要买电脑--我要明确买电脑的意义--上网查对应的参数信息--去中关村买电脑--讨价还价--买回电脑
 * 			面向对象:我要买电脑--班长去给我买电脑--买回电脑
 * 		洗衣服:
 * 			面向过程:把衣服脱下来--找一个盆--放点洗衣粉--加点水--浸泡10分钟--揉一揉--清洗衣服--拧干--晾起来
 * 			面向对象:把衣服脱下来--打开全自动洗衣机--扔衣服--按钮--晾起来
 */
/*
 * 我们学习编程语言,其实就是为了把现实世界的事物模拟出来,实现信息化。
 * 
 * 我们是如何表示现实世界的事物的呢?
 * 		A:属性	就是事物的描述信息
 * 		B:行为	就是事物能够做什么
 * 		举例:学生
 * 
 * Java语言最基本的单位是类,所以,我们在后面的学习过程中,是通过类来体现现实世界事物的。
 * 
 * 类:是一组相关的属性和行为的集合
 * 对象:就是该事物的具体体现
 * 		举例:
 * 			类		学生
 * 			对象		班长
 */
/*
 * 类的定义:
 * 		类是用来描述现实世界的事物的
 * 
 * 事物:
 * 		属性	事物的描述信息
 * 		行为	事物能够做什么
 * 
 * 类是如何和事物进行对应的呢?
 * 		类:
 * 			成员变量
 * 			成员方法
 * 
 * 需求:写一个学生类
 * 
 * 学生事物:
 * 		属性:姓名,年龄...
 * 		行为:学习,吃饭...
 * 
 * 学生类:
 * 		成员变量:姓名,年龄
 * 		成员方法:学习,吃饭
 *
 * 成员变量:和我们前面学习过的变量的定义是一样的。
 * 		位置不同:类中,方法外
 * 		初始化值:不需要给初始化值
 * 成员方法:和我们前面学习过的方法的定义是一样的。
 * 		去掉static关键字
 */
/*
 * Student是一个学生事物描述类,main方法不适合放在它里面。
 * 
 * 使用一个类,其实就是使用该类的成员。(成员变量和成员方法)
 * 而我们要想使用一个类的成员,就必须首先拥有该类的对象。
 * 我们如何拥有一个类的对象呢?
 * 		创建对象就可以了?
 * 我们如何创建对象呢?
 * 		格式:类名 对象名 = new 类名();
 * 对象如何访问成员呢?
 * 		成员变量:对象名.变量名
 * 		成员方法:对象名.方法名(...)
 */
/*
 * 成员变量和局部变量的区别:
 * 		A:在类中的位置不同
 * 			成员变量:类中,方法外
 * 			局部变量:方法中或者方法声明上(形式参数)
 * 		B:在内存中的位置不同
 * 			成员变量:堆内存
 * 			局部变量:栈内存
 * 		C:生命周期不同
 * 			成员变量:随着对象的创建而存在,随着对象的消失而消失
 * 			局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
 * 		D:初始化值的问题
 * 			成员变量:有默认值
 * 			局部变量:没有默认值。必须先定义,赋值,最后使用
 */

成员变量和局部变量的区别

A:位置不同

​ 成员变量:类中。方法外

​ 局部变量:方法中或者方法声明上。(形式参数)

B:内存中的位置不同

​ 成员变量在堆内存中

​ 局部变量:在栈内存中

生命周期不同

​ 成员变量:随着对象的创建而存在,随着对象的消失而消失

​ 局部变量:随着方法的调用而存在,随着方法的消失而消失

出事化问题:

​ 成员变量有默认值

​ 局部变量没有默认值,使用的时候必须先赋值

修饰符

如果不想让外界的变量直接访问成员变量使用private

private:只能在本类访问,针对private修饰的成员变量,我们会提供相应的get;和set;方法。用于获取和设置成员变量的值。方法用pulibc修饰

public:所有地方都可以进行访问。

this关键字

this代表所在对象的引用

构造函数

和类名相同的没有返回值得函数

可以进行重载。

可以定义多个不同的参数列表。

没有定义构造函数的时候系统默认会有一个没有参数的构造函数

如 果定义了一个构造函数,系统就不会自动生成无参数的构造函数。

08.常用API

API概述

api(application programming interface):应用程序编程接口

也称为了帮助文档

###使用方法:

1:打开帮助文档
2:点击显示,找到索引,看到输入框
3:你要学习什么内容,你就在框框里面输入什么内容

举例:Random

4:看包
java.lang包下的类在使用的时候是不需要导包的
5:看类的描述
Random类是用于生成随机数的类
6:看构造方法

Random():无参构造方法
	Random r = new Random();

7:看成员方法

public int nextInt(int n):产生的是一个[0,n)范围内的随机数
	调用方法:
		看返回值类型:人家返回什么类型,你就用什么类型接收
		看方法名:名字不要写错了
		看形式参数:人家要几个参数,你就给几个,人家要什么数据类型的,你就给什么数据类型的
		
		int number = r.nextInt(100);

java.lang下的包是不需要导入得

//String键盘输入小练习
package com.itheima;

import java.util.Scanner;

public class MyString {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入一个字符串类型的数据");
		String s = sc.nextLine();
		System.out.print(s);
	}
}

创建字符串的四种方式

package com.itheima_02;
/*
 * String:字符串类
 * 		由多个字符组成的一串数据
 * 		字符串其本质是一个字符数组
 * 
 * 构造方法:
 * 		String(String original):把字符串数据封装成字符串对象
 * 		String(char[] value):把字符数组的数据封装成字符串对象
 * 		String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象
 * 
 * 注意:字符串是一种比较特殊的引用数据类型,直接输出字符串对象输出的是该对象中的数据。
 */
public class StringDemo {
	public static void main(String[] args) {
		//方式1
		//String(String original):把字符串数据封装成字符串对象
		String s1 = new String("hello");
		System.out.println("s1:"+s1);
		System.out.println("---------");
		
		//方式2
		//String(char[] value):把字符数组的数据封装成字符串对象
		char[] chs = {'h','e','l','l','o'};
		String s2 = new String(chs);
		System.out.println("s2:"+s2);
		System.out.println("---------");
		
		//方式3
		//String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象
		//String s3 = new String(chs,0,chs.length);
		String s3 = new String(chs,1,3);
		System.out.println("s3:"+s3);
		System.out.println("---------");
		
		//方式4
		String s4 = "hello";
		System.out.println("s4:"+s4);
	}
}

####通过构造函数直接创建字符串和直接赋值方式创建的字符串对象用什么区别呢

/*==:
	比较基本数据类型的时候是比较的基本数据类型的值是否相同。
	比较引用数据类型的时候比较的是地址值是否相同
*/
直接赋值的方式。创建的两个对象他们的地址值是相同的。
字符串总的内容是存储在方法区的常量池中。是为了方便字符串的重复使用
常量池中字符串的重复使用问题

String比较方法

package com.itheima_03;
/*
 * Object:是类层次结构中的根类,所有的类都直接或者间接的继承自该类。
 * 如果一个方法的形式参数是Object,那么这里我们就可以传递它的任意的子类对象。
 * 
 * String类的判断功能:
 * boolean equals(Object obj):比较字符串的内容是否相同
 * boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
 * boolean startsWith(String str):判断字符串对象是否以指定的str开头
 * boolean endsWith(String str):判断字符串对象是否以指定的str结尾
 */
public class StringDemo {
	public static void main(String[] args) {
		//创建字符串对象
		String s1 = "hello";
		String s2 = "hello";
		String s3 = "Hello";
		
		//boolean equals(Object obj):比较字符串的内容是否相同
		System.out.println(s1.equals(s2));
		System.out.println(s1.equals(s3));
		System.out.println("-----------");
		
		//boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
		System.out.println(s1.equalsIgnoreCase(s2));
		System.out.println(s1.equalsIgnoreCase(s3));
		System.out.println("-----------");
		
		//boolean startsWith(String str):判断字符串对象是否以指定的str开头
		System.out.println(s1.startsWith("he"));
		System.out.println(s1.startsWith("ll"));
      	System.out.println("-----------");
      
      	System.out.println(s1.startsWith("he"));
		System.out.println(s1.startsWith("ll"));
	}
}
//Test
package com.itheima;

import java.util.Scanner;

public class Demo1 {
	private static Scanner sc;

	public static void main(String[] args) {
		String admin="admin";
		String password="Password";
		
		sc = new Scanner(System.in);
		
		
		for(int i =0; i<3;i++){
			String admin1 = sc.nextLine();
			String password1 = sc.nextLine();
			
			if(admin1.equals(admin)&&password1.equals(password) ){
				System.out.print("gamestart");
				break;
			}
			else{
				System.out.print("重新输入吧哥们");
			}
		}
	}
}

String获取方法

package com.itheima_04;
/*
 * String类的获取功能:
 * int length():获取字符串的长度,其实也就是字符个数
 * char charAt(int index):获取指定索引处的字符
 * int indexOf(String str):获取str在字符串对象中第一次出现的索引
 * String substring(int start):从start开始截取字符串
 * String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end
 */
public class StringDemo {
	public static void main(String[] args) {
		//创建字符串对象
		String s = "helloworld";
		
		//int length():获取字符串的长度,其实也就是字符个数
		System.out.println(s.length());
		System.out.println("--------");
		
		//char charAt(int index):获取指定索引处的字符
		System.out.println(s.charAt(0));
		System.out.println(s.charAt(1));
		System.out.println("--------");
		
		//int indexOf(String str):获取str在字符串对象中第一次出现的索引
		System.out.println(s.indexOf("l"));
		System.out.println(s.indexOf("owo"));
		System.out.println(s.indexOf("ak"));
		System.out.println("--------");
		
		//String substring(int start):从start开始截取字符串
		System.out.println(s.substring(0));
		System.out.println(s.substring(5));
		System.out.println("--------");
		
		//String substring(int start,int end):从start开始,到end结束截取字符串
		System.out.println(s.substring(0, s.length()));
		System.out.println(s.substring(3,8));
	}
}

String类的转化功能

package com.itheima_05;
/*
 * String类的转换功能:
 * char[] toCharArray():把字符串转换为字符数组
 * String toLowerCase():把字符串转换为小写字符串
 * String toUpperCase():把字符串转换为大写字符串
 * 
 * 字符串的遍历:
 * 		A:length()加上charAt()
 * 		B:把字符串转换为字符数组,然后遍历数组
 */
public class StringDemo {
	public static void main(String[] args) {
		//创建字符串对象
		String s = "abcde";
		
		//char[] toCharArray():把字符串转换为字符数组
		char[] chs = s.toCharArray();
		for(int x=0; x<chs.length; x++) {
			System.out.println(chs[x]);
		}
		System.out.println("-----------");
		
		//String toLowerCase():把字符串转换为小写字符串
		System.out.println("HelloWorld".toLowerCase());
		//String toUpperCase():把字符串转换为大写字符串
		System.out.println("HelloWorld".toUpperCase());
	}
}

字符串的其他功能

package com.itheima_06;
/*
 * 去除字符串两端空格	
 *		String trim()
 * 按照指定符号分割字符串	
 *		String[] split(String str)
 */
public class StringDemo {
	public static void main(String[] args) {
		//创建字符串对象
		String s1 = "helloworld";
		String s2 = "  helloworld  ";
		String s3 = "  hello  world  ";
		System.out.println("---"+s1+"---");
		System.out.println("---"+s1.trim()+"---");
		System.out.println("---"+s2+"---");
		System.out.println("---"+s2.trim()+"---");
		System.out.println("---"+s3+"---");
		System.out.println("---"+s3.trim()+"---");
		System.out.println("-------------------");
		
		//String[] split(String str)
		//创建字符串对象
		String s4 = "aa,bb,cc";
		String[] strArray = s4.split(",");
		for(int x=0; x<strArray.length; x++) {
			System.out.println(strArray[x]);
		}
	}
}

字符串做拼接是非常耗时的而且浪费空间。StringBuild可以解决这个问题

StringBuild类及其构造方法

package com.itheima_01;
/*
 * StringBuilder:是一个可变的字符串。字符串缓冲区类。
 * 
 * String和StringBuilder的区别:
 * 		String的内容是固定的。
 * 		StringBuilder的内容是可变的。
 * 
 * 构造方法:
 * 		StringBuilder()
 * 
 * 成员方法:
 * 		public int capacity():返回当前容量
 * 		public int length():返回长度(字符数)
 * 
 * 		容量:理论值
 * 		长度:实际值
 */
public class StringBuilderDemo {
	public static void main(String[] args) {
		//创建对象
		StringBuilder sb = new StringBuilder();
		System.out.println("sb:"+sb);
		System.out.println("sb.capacity():"+sb.capacity());
		System.out.println("sb.length():"+sb.length());
	}
}

返回自身的对象可以进行链式调用

package com.itheima_02;
/*
 * 添加功能
 *		public StringBuilder append(任意类型):添加数据,并返回自身对象
 * 反转功能
 *		public StringBuilder reverse()
 */
public class StringBuilderDemo {
	public static void main(String[] args) {
		//创建对象
		StringBuilder sb = new StringBuilder();
		
		//public StringBuilder append(任意类型)
		//StringBuilder sb2 = sb.append("hello");
		
		/*
		System.out.println("sb:"+sb);
		System.out.println("sb2:"+sb2);
		System.out.println(sb == sb2); //true
		*/
		
		/*
		sb.append("hello");
		sb.append("world");
		sb.append(true);
		sb.append(100);
		*/
		
		//链式编程
		sb.append("hello").append("world").append(true).append(100);
		
		System.out.println("sb:"+sb);
		
		//public StringBuilder reverse()
		sb.reverse();//反转功能
		System.out.println("sb:"+sb);
		
	}
}

Stringbuilder和String互相转话

package com.itheima_03;
/*
 * StringBuilder和String的相互转换
 * 
 * StringBuilder -- String
 * 		public String toString():通过toString()就可以实现把StringBuilder转成String
 * 
 * String -- StringBuilder
 * 		StringBuilder(String str):通过构造方法就可以实现把String转成StringBuilder
 */
public class StringBuilderTest {
	public static void main(String[] args) {
		//StringBuilder -- String
		/*
		StringBuilder sb = new StringBuilder();
		sb.append("hello").append("world");
		
		String s = sb.toString();
		System.out.println(s);
		*/
		
		//String -- StringBuilder
		String s = "helloworld";
		StringBuilder sb = new StringBuilder(s);
		System.out.println(sb);
	}
}

09.java集合

对象数组

//主要的类
package com.itheima;

public class StudentDemo {
	public static void main(String[] args) {
		StudentClass[] stuarry = new StudentClass[3];
		
		StudentClass stu1 = new StudentClass("李元芳",18);
		StudentClass stu2 = new StudentClass("李元芳1",954);
		StudentClass stu3 = new StudentClass("李元芳2",78);
		
		stuarry[0]=stu1;
		stuarry[1]=stu2;
		stuarry[2]=stu3;
		
		for (int i = 0; i < stuarry.length; i++) {
			stuarry[i].call();
		}
	}
}
//学生类
package com.itheima;

public class StudentClass {
	String name;
	int age;
	public void call(){
		System.out.println("恰饭");
	}
	public StudentClass(){
		
	}
	public StudentClass(String name,int age){
		this.age=age;
		this.name=name;
	}
}

集合类

集合类的特点,长度可变。

ArryList类的使用

//ArryList<E>:<E>为泛型,再出现E的地方使用引用数据类型替换就好了
//构造方法  
ArryList<String> array = new ArrayList<String>();
System.out.println(array);//输出的是[],想要打印的是集合中的元素,但是没有元素是空的,所以就这样了

//添加元素的方法:
    array.add("你好");
    array.add("你好1");
    array.add("你好2");
    array.add("你好3");
    array.add("你好4");
    array.add("你好5");
//在指定位置添加元素
	array.add(1,"你好");

//获取元素:
	array.get(2);//返回指定索引出的元素。
	array.size();//返回列表中元素个数
	
//删除元素:remove(Object o)
	array.remove();//删除指定的元素,返回删除是否成功
	array.remove(int index);//删除指定索引的元素.返回删掉的元素

//修改元素
	array.set(int index,E element);//修改指定索引处的元素,返回被修改的元素。

练习:

存储字符串并遍历,并且打印所有姓张的人。

10.IO操作

IO流

用途:

​ 1、可以把数据存储到文件

​ 2、可以从文件中读取数据

应用:

​ 1、文件拷贝

​ 2、上传文件

​ 3、下载文件

IO流分类

分类

​ 输入:

​ FileWriter

​ 使用方法:

​ A:创建输出流对象

​ B:调用输出流对象的写数据方法

​ C:释放资源

//创建资源
FileWriter fw = new FileWriter("d:\\a.txt");//如果没有写盘符,就会在本程序的文件夹下创建文件。 
fw.write("IO你好");//写完的时候输存到了缓存区中,并没有写到文件中
fw.flush();//刷新一下,让缓存区中的数据,写入到文件中。
//程序在运行的时候如果没有告诉程序释放资源,程序会一直运行使用文件。
fw.close();//告诉程序释放资源。释放和该文件相关的资源因为这个文件是我们调用系统资源创建的。
/*
 * void write(String str):写一个字符串数据
 * void write(String str,int index,int len):写一个字符串中的一部分数据
 * void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
 * void write(char[] chs):写一个字符数组数据
 * void write(char[] chs,int index,int len):写一个字符数组的一部分数据
 
 fswriter使用的时候是使用覆盖的模式。
 使用追加模式:
 	FileWriter(String FileName, boolean true);//追加模式
 
 /n可以实现换行,但是windows自带的记事本打开并不会换行,因为windows识别的换行不是/n而是/r/n。
 
 */

​ 输出:

​ FileRead

​ 使用方法:

​ A:创建输入流对象。

​ B:调用输入流对象的写数据方法。

​ C:释放资源。

​ 构造方法:

​ FileReader fr= new FileReader(String filepath);

FileReader fr = new FileReader
//调用读取数据的方法。
ch = int read();//一次读取一个字符,而且返回的都是整数类型。char类型需要强制转换为char类型的数据才可以正确显示。要不然只能显示字母对应的整数。
System.out.println(ch);//97
System.out.println((char)ch);//98

int ch1 = fr.read();
//当所有的文本都读取完了的时候会返回-1;这个可以作为一个循环条件。
fr.close();

/*
输入流读数据的步骤
	A:创建输入流的对象
	B:调用输入流对象的读数据的方法
	C:释放资源
*/
int read(char[] cbuf)://返回的是读取数据的实际长度,一次读取一个字节数组的数据
/*
读取的时候是从上次读取的最后为开始,一直读取到所设置的长度,换行符为/r/n读取的时候也是占位置的。

例子:
读取字符串			abcdefg
					hijklmn
如果一直读取五个字符。
会先读取abcde,存储到数组中
然后在读取五个fg/r/nh覆盖abcde,存储到数组中
然后读取ijkln覆盖fg/r/nh
最后读取n的时候也是进行覆盖读取到的字符串就是ng/r/nh
当我们实际读取长度是-1的时候说明没有数据了。
暂时理解就是这样(2019-7-28)
*/

练习复制一个文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//使用IO操作来复制文件,针对字符流文件
public class MyIOTest {
	public static void main(String[] args) throws IOException {
//		FileReader fr = new FileReader("copy.txt");
//		FileWriter fw = new FileWriter("copy3.txt");
		
		//第一种方法,使用单个字符读取
//		int ch;
//		while((ch=fr.read())!=-1){
//			fw.write(ch);
//		}
		
		//第二种方法使用一个数组读取
//		char[] chs = new char[1024];
//		int len;
//		while((len = fr.read(chs))!=-1){
//			System.out.print(len);
//			System.out.print(new String(chs,0,len));
//			fw.write(chs,0,len);
//		}
		
		
		
		
		//第三种方法使用缓冲字符流读取单个字符
//		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
//		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy4.txt"));
//		int ch;
//		while((ch=bfr.read())!=-1){
//			bfw.write(ch);
//		}
//		bfr.close();
//		bfw.close();
//		
		
		
		//第四种方法使用缓冲字节流读取一个数组
//		
//		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
//		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy5.txt"));
//		
//		char[] chs = new char[1024];
//		int len;
//		
//		while((len=bfr.read(chs))!=-1){
//			bfw.write(chs,0,len);
//		}
//		bfr.close();
//		bfw.close();
		
		
		//第五种方法,使用缓冲字节流读取字符串
		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy6.txt"));
		
		String str;
		while(((str = bfr.readLine()) !=  null )){
			bfw.write(str);
			bfw.newLine();
			bfw.flush();
		}
		bfr.close();
		bfw.close();
//		
//		fr.close();
//		fw.close();
	}
}

BufferedStream

缓冲字符流,可以将文本写入字符输出流,缓冲哥哥字符,从而提供的那个字,数组和字符串的高效写入。

buffeeWriter(writer 对象);
newline();//系统自动添加合适的换行符。
读取字符串的时候没有数据返回的是null

11.复习和static

static用于修饰成员变量和成员方法

被static修饰的对象,可以对所有对象共享。所以不属于特定的对象,使用类名代用。但是也可以使用对象调用,使用对象调用会出现报错。

静态方法和静态字段。

今天的加载优先于对象的加载,随着类的加载而加载。

加载字节码对象的时候加载到内存的方法区中。

静态方法可以调用静态方法。静态方法可以调用静态变量

静态方法中只能调用静态方法

非静态方法可以调用静态方法。

静态方法中没有this这个方法。

代码块{}

在以前的位置上加上{}感觉没有什么用。

局部代码块的作用:变短变量的生命周期。{}中被认为是下一级

构造代码块:直接放在类中和构造方法,只要创建对象就会执行一次。抽取构造函数中的共性

静态代码块:构造代码块前面添加static,只执行一次

12.集成和抽象类

继承

关键字:extends

特点:

​ 1、只支持单一继承。只能继承一个父类。(一个儿子只能有一个亲爹,但是可以有很多干爹。一个亲爹可以有很多儿子)

​ 2、java语言支持多层继承(可以有亲爹和亲爷爷)

​ 3、子类只能获取非私有成员。(private修饰的成员变量和方法不会被继承)

​ 4、使用元素的规则为就近原则。(父类和子类中有相同的成员变量的时候调用比较近的那个。局部变量和全局变量也是)

public class MyDemo01 {
	public static void main(String[] args) {
		Cat cat = new Cat();//子类创建了对象
		cat.name="猫";//子类继承了父类中的变量
		System.out.println(cat.name);
      
		System.out.println(cat.age);//子类中有和父类中相同的变量,使用子类中的变量值。
      
		cat.eat();//子类重写了父类中的方法
      
		Dog dog = new Dog();
		dog.name="狗";
      
		System.out.println(dog.age);//子类中有和父类中相同的变量,使用子类中的变量值。
      
		System.out.println(dog.name);
//		dog.active="喝酒";//报错父类中的此方法是私有的。不会被继承到子类中。
		//System.out.println(dog.active);
		dog.eat();
	}
}
class Animoal{//父类
	String name;
	int age=60;
	String gender;
	private String active;
	public  void eat(){
		System.out.println("正在吃饭");
	}
}
class Cat extends Animoal {//继承父类的子类
	int age=90;//和父类中的变量一样
	public void eat(){//重写了父类中方法
		System.out.println("正在吃鱼");
	}
} 
class Dog extends Animoal{
	public void eat(){
		System.out.println("正在吃骨头");
	}
}

重写

方法的重写:子类的方法和父类的方法完全一样。子类的方法重写(覆盖)了父类的方法。

条件:子类中的权限修饰符需要大于等于父类中的权限修饰符。(public>protected >private)

public class MyDemo02 {
	public static void main(String[] args) {
		Cat1 cat = new Cat1();
		cat.eat();
		Dog2 dog = new Dog2();
		dog.eat();
	}
}
class Animoal1{
	public  void eat(){
		System.out.println("正在吃饭");
	}
}
class Cat1 extends Animoal1 {
	int age=90;
	public void eat(){
		System.out.println("正在吃鱼");
	}
} 
class Dog2 extends Animoal1{
//	private void eat(){//这里重写的等级比父类中的等级低,所以会报错
//		System.out.println("正在吃骨头");
//	}
}

方法重载:一个类中有多个重名方法,但是参数不一样。(参数个数,类型和数量不一样。)

父类和子类中有相同的方法名,调用顺序是就近原则。(方法的重写)

构造方法的调用顺序

1、在执行子类构造方法的时候,子类构造方法的第一行如果没有调用子类构造方法,或者父类构造方法,就会默认调用父类无参构造方法。

2、肯定要先执行父类的构造,因为要先初始化父类的成员变量。

3、构造方法第一行要么调用父类的构造,要么调用子类的构造。什么都不写默认调用父类的无参构造方法。

public class MyDemo01 {
	public static void main(String[] args) {
		Baby baby = new Baby();
		System.out.println("-----------------------------------------------------------");
		Baby baby1 = new Baby(1);
	}
}
class Father{
	public  Father(){
		System.out.println("这里是父类的无参构造");
	}
	public Father(int num){
		System.out.println("这里是父类的有参构造");
	}
}
class Baby extends Father{
	public  Baby(){
		this(5);
		System.out.println("这里是子类的无参构造");
	}
	public Baby(int num){
		System.out.println("这里是子类的有参构造");
	}
	
}

打印的结果为

这里是父类的无参构造
这里是子类的有参构造
这里是子类的无参构造
-------------------
这里是父类的无参构造
这里是子类的有参构造

##super关键字

super:super关键字可以代表父类,可以使用super调用父类的变量和方法。以及构造方法。(构造方法只能在子类中的构造方法的第一行调用。),使用方法和this相似。

public class MyDemo01 {
	public static void main(String[] args) {
		Baby baby = new Baby();
		baby.eat();
	}
}
class Father{
	String name ="hello";
	String age = "9494";
	public void eat(){
		System.out.println("这是父类的吃东西方法");
	}
}
class Baby extends Father{
	public  Baby(){
		super.eat();
	}
	public void eat(){
		super.eat();
		System.out.println("这是子类吃饭的方法");
	}
}

下面是运行结果

这是父类的吃东西方法
这是父类的吃东西方法
这是子类吃饭的方法

This 和 Super区别

区别:

​ this调用当前对象

​ super调用父类对象。

注意:

​ 当this调用一个父类中存在但是子类中没有存在的方法或者变量的时候会默认调用父类中的方法。这个时候this表示父类

###注解:@开头写在方法上面,类上面,变量上面,用来描述类和方法的。

​ 可以通过代码来描述代码。

@Override//表示描述重写父类的方法。

抽象类

特点:

​ 1、abstract关键字用于修饰方法和类。

​ 2、abstract修饰的类中不一定有abstract修饰的方法,但是abstract修饰的方法一定存在于abstract修饰的类中。

​ 3、abstract修饰的方法不能进行实例化。

​ 4、abstract修饰的类被普通类继承,普通类需要把abstract中的所有抽象方法进行实现。

​ 5、abstract修饰的类被abstract修饰的类继承的话,不需要把抽象方法实现。

​ 6、抽象类中可以有普通的变量和普通的方法。也可以有抽象方法

​ 7、抽象类中可以有构造函数。(虽然不能实例化,但是可以有构造函数)因为构造函数的作用是加载类中的其他成员,而抽象类有其他成员。并且可以被继承。(继承的时候子类会默认调用父类的无参构造函数。)

​ 8、声明的抽象方法都不能有代码块。需要等着子类来实现。

​ 9、抽象类和抽象方法必须被修饰。

public class MyDemo01 {
	public static void main(String[] args) {
//		Father fa = new Father();//报错不能实现
		
		Baby baby = new Baby();
		baby.eat();
	}
} 
abstract class Father{
	public  Father(){
		System.out.println("父类的构造方法");
	}
	String name ="hello";
	String age = "9494";
	public void eat(){
		System.out.println("这是父类的吃东西方法");
	}
	abstract void drink();
}
class Baby extends Father{
	public  Baby(){
		super.eat();
	}
	public void eat(){
		System.out.println("这是子类吃饭的方法");
	}
	public void drink(){
		System.out.println("喝水");
	}
}

下面是打印结果

父类的构造方法
这是父类的吃东西方法
这是子类吃饭的方法

###final:修饰类,成员变量,成员方法、

​ 修饰的类不能被继承

​ 修饰的成员变量不能被修改

修饰成员方法不能被重写。

13.接口和多肽

接口interface

格式:

​ interface 接口名{}

功能:

​ 1、解决只能单一继承的问题。

特点:

​ 1、接口中只能有抽象方法。默认都是抽象方法。

​ 2、接口不能实例化。

总结:

​ 1、一个类可以继承多个接口,因为接口中的所有方法都是抽象方法(默认添加public & abstract 在方法前面,不能使用其他修饰符修饰。)建议手动添加修饰符。

​ 2、接口中的所有变量都是常量(默认在变量前面添加了public & static & final 修饰符。)

​ 3、类和接口的关系只有实现(implements)关系。和抽象函数的继承不同

​ 4、 接口的继承要使用implements

优点:

​ 1、类与接口的关系:多实现过关系。类与类之间是单一继承关系,一个类只能有一个父类。接口的出现打破了继承的局限性。

​ 2、对外提供规则。

​ 3、降低了程序的耦合性。

接口和抽象类的区别:

​ 共性:不断抽取,抽取出抽象的概念

​ 区别1:与类的关系。

​ 类与接口的实现关系,而且是多实现,一个类可以有多个接口。

​ 类与抽象类的关系是继承关系。java中的继承是单一继承,多层继承。

​ 区别2:抽象类,可以有成员变量和普通方法,常量。但是接口只能有常量,只能有抽象方法。

​ 抽象类有构造方法。接口没有构造方法。

public class InterfaceDemo01 {
	public static void main(String[] args) {
		BaskBallPlayer bbp = new BaskBallPlayer();
		bbp.name="养殖";
		bbp.age=54;
		bbp.gender="男";
		bbp.speak();
		bbp.study();
		bbp.eat();
		bbp.sleep();
	}
}
//人类
class Person{
	String name;
	int age;
	String gender;
	public Person(){
		
	}
	public Person(String name, int age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public void sleep(){
		System.out.println("睡觉");
	}
	public void eat(){
		System.out.println("恰饭");
	}
}
//运动员类
abstract class Player extends Person{
	public abstract void study();
}
//教练类
abstract class Teacher extends Person{
	public abstract void teach();
}
//篮球运动员
class BaskBallPlayer extends Player implements English{

	@Override
	public void study() {
		System.out.println("学习扣篮");
	}
	public void speak(){
		System.out.println("说英语");
	}
	
}
//乒乓球运动员
class PingPangPlayer extends Player{
	public void study(){
		System.out.println("学习抽球");
	}
}
//篮球教练
class BaskBallTecaher extends Teacher implements English{
	public void teach(){
		System.out.println("教扣篮");
	}
	public void speak(){
		System.out.println("说英语");
	}
}
//乒乓球教练
class PingPangTecaher extends Teacher{
	public void teach(){
		System.out.println("教抽球");
	}
}
interface English{
	public void speak();
}

匿名函数

普通情况:

​ Student s = new Student();

​ s.study();

匿名函数情况:

​ new Student().study();

​ 普通函数能够做到的事情匿名函数都可以做到。

使用情况:

​ 当方法只调用一次的时候我们可以使用匿名函数。

​ 匿名函数每使用一次就新创建一个新的。

​ 赋值并没有意义。

匿名函数的特点:

​ 1、在只是用一次的时候创建

​ 2、没使用一次就创建一个新的,所以赋值操作完全没有作用。

public class Function {
	public static void main(String[] args) {
		Student s = new Student();
		s.study();
		
		new Student().study();
	}
	
}
class Student{
	public void study(){
		System.out.println("正在学习");
	}
}

Final修饰符

final可以修饰类,成员方法,成员变量。

final修饰的成员方法,和成员变量的效果:

​ final修饰的类为最终的类,不能被继承

​ final修饰的方法为最终的方法,不能被重写。

​ final修饰的变量为常量。不能被更改。

常量命名,全部使用大写字符。如果是多个单词中间使用下划线分割。常量命名的时候必须初始化。可以选择显示初始化,或者构造初始化。

多态

前提:

​ 子父继承关系

​ 方法的重写

​ 父类引用指向子类对象

缺点:

​ 无法直接访问子类特有的成员。编译期间访问的是父类型

优点:

​ 可以提高代码的可维护性。(多态前提多提供的),提高代码的可扩展性

概念:

​ 多态是同一个行为具有多个不同表现形式或形态的能力。

​ 多态就是同一个接口,使用不同的实例而执行不同操作。

实例

public class DuoTaiDemo {
	public static void main(String[] args) {
		Father f = new Student1();
		f.teach();
	}
}
class Father{
	public void teach(){
		System.out.println("这里是父类");
	}
}
class Student1 extends Father{
	public void teach(){
		System.out.println("这里是studnet1");
	}
}
class Student2 extends Father{
	public void teach(){
		System.out.println("这里是studnet2");
	}
}
//运行结果为:这里是studnet1

运行期间:调用的方法是根据其具体类型。(子类对象指向父类对象,调用的是子类的方法。动态绑定)(成员变量没有动态绑定所以运行的时候依旧会运行父类的成员变量。)

编译期间:根据的是左边f的类型,father类寻找变量和方法。如果没有在父类中找到对应的方法就会报错。

如果子类中有父类中没有存的方法。那么如果在编译期间就进行调用的话,会直接报错。不能使用。如果调用父类中存在,子类中也存在的方法,最终调用具体的方法。(就像是狗是动物,让动物吃饭的时候还是狗去吃饭一个道理)

多态可以使用父类来就收对象,然后调用子类的方法。

引用类型之间的转换

向上转化:

​ 默认的转化方法:

​ Father f = new Student1();//默认发生了由子类向父类的转化

向下转化

​ 需要强制转化。转化方法和基本数据类型一样。

​ Student1 f1 = (Student1) f;//只能狗转化为狗,猫转化为猫,不能猫转化为狗。

14.包和修饰符

作用:

​ 帮我们分类管理我们的文件夹。管理我们的项目(包的命名都是小写)

特点:

​ 1、可以有多层结构,多层结构用.来调用

​ 2、不同包下的文件名可以重复

​ 3、用package来分割,包的生命必须是第一行代码。

不同包之间的互相访问

1、使用类的全名(包名+类名)

2、使用import导入(import java.util.ArrayList;)

3、全部导入import java.util.*(导入java.util包下所有的类。并没有导入子包下的类。util下的包中的类没有导入。)

4、ctrl+1提示导入

修饰符

权限修饰符

public (共有的):当前类,相同包下的类,不同包下的类,都可以访问。

default(默认的):如果不加修饰符默认使用default。当前类,相同包下不同的类。

private(私有的):只能在当前类中使用

​ 不能修饰类,可以修饰成员变量,成员方法,构造方法

protected(受保护的):当前类,相同包下不同的类,子类。

​ 不能修饰类,可以修饰成员变量,成员方法,构造方法

其他修饰符

abstract

​ 可以修饰类,不能修饰变量,能够修饰方法,不可以修饰构造方法

static

​ 只能修饰成员变量,成员方法

final

​ 可以修饰类,成员变量,成员方法,不能修饰构造方法

常见规则:

​ 若果我们使用public来修饰一个类,一个java文件下只能有一个类,如果一个java文件下有多个类,那么与文件名相同的那个类,就必须使用public来修饰,其他的类不能使用public来修饰,

​ 以后所有的成员变量都使用private来修饰。

​ 以后所有的方法使用pulibc修饰

​ 以后所有的构造方法使用public来修饰

​ 如果不想创建对象使用Private来修饰。

内部类

成员内部类

位置:和成员变量和成员方法的位置一样。

创建对象:

​ 成员内部类的方法中使用:创建对象在一个类的内部。如果外部想要使用这个类,那就需要在该文件下导入这个类,或者使用外部类.内部类的名字,才可以使用。

OutClass.Inner ins1 = new OutClass().new Inner();//创建一个对象即可。

使用private类修饰成员内部类,在其他类中将无法访问。

可以使用static修饰成员内部类,不用再创建外部对象了。

abstract和final都可以修饰类。

成员内部类的使用方法
//1、在自己的类中调用方法
public class MyTest01 {
	public static void main(String[] args) {
		OutClass oc = new OutClass();
		oc.newinner();
	}
}
class OutClass{
	
	public void call(){
		System.out.println("外部类");
	}
	
	public void newinner(){
		Inner ins = new Inner();
		ins.speak();
	}
	class Inner{
		public void speak(){
			System.out.println("内部类");
		}
	}
}
//2、在外部调用成员内部类
public class MyTest01 {
	public static void main(String[] args) {
		OutClass.Inner ins1 = new OutClass().new Inner();
		ins1.speak();
	}
}
class OutClass{
	
	public void call(){
		System.out.println("外部类");
	}
	
	public void newinner(){
		Inner ins = new Inner();
		ins.speak();
	}
	class Inner{
		public void speak(){
			System.out.println("内部类");
		}
	}
}
//3、类用静态修饰的时候
public class MyTest01 {
	public static void main(String[] args) {
		OutClass.Inner ins1 = new OutClass.Inner();
		ins1.speak();
	}
}
class OutClass{
	
	public void call(){
		System.out.println("外部类");
	}
	
	public void newinner(){
		Inner ins = new Inner();
		ins.speak();
	}
	static class Inner{
		public void speak(){
			System.out.println("内部类");
		}
	}
}
//4、使用import的时候
import com.itheima.OutClass.Inner;

public class MyTest01 {
	public static void main(String[] args) {
		Inner ins1 = new OutClass().new Inner();
	}
}
class OutClass{
	
	public void call(){
		System.out.println("外部类");
	}
	
	public void newinner(){
		Inner ins = new Inner();
		ins.speak();
	}
	class Inner{
		public void speak(){
			System.out.println("内部类");
		}
	}
}

局部内部类

位置:

​ 在一个类的方法中创建。

创建对象:

​ 使用需要在声明之后才能创建对象。

​ 如果想在其他方法中创建内部类对象怎么办

public class MyTest01 {
	public static void main(String[] args) {
		OutClass oc = new OutClass();
		oc.newinner();
	}
}
class OutClass{
	
	public void call(){
		System.out.println("外部类");
	}
	
	public void newinner(){
		
		class Inner{
			public void speak(){
				System.out.println("内部类");
			}
		}
		
		Inner ins = new Inner();
		ins.speak();
	}
}

匿名内部类

匿名内部类可以看成一个没有名字的局部内部类。定义在方法当中。匿名内部类必须在定义匿名内部类的时候创建对象

格式:

​ new 类或者接口(){};

​ 如果是创建了继承这个类的子类对象。我们可以重写父类的方法。

​ 如果创建了实现这个接口的子类对象,我们必须要实现该接口的所有方法。

原理:

​ 创建了继承这个类的子类对象,或者创建了实现这个接口的子类对象。

直接当对象使用

使用父类来接收,然后使用方法是以前一样。

//1、直接使用
public class MyTest01 {
	public static void main(String[] args) {
		OutClass oc = new OutClass();
		oc.newinner();
	}
}
class OutClass{
	public void call(){
		System.out.println("外部类");
	}
	public void newinner(){	
		new Inner(){
			public void speak(){
				System.out.println("这里是匿名内部类。");
			}
		}.speak();
	}
}
class Inner{
	public void speak(){
		System.out.println("内部类");
	}
}
//2、当做参数传递给父类
public class MyTest01 {
	public static void main(String[] args) {
		OutClass oc = new OutClass();
		oc.newinner();
	}
}
class OutClass{
	public void call(){
		System.out.println("外部类");
	}
	public void newinner(){	
		Inner inte = new Inner(){
			public void speak(){
				System.out.println("这里是匿名内部类。");
			}
		};
		inte.speak();
	}
}
class Inner{
	public void speak(){
		System.out.println("内部类");
	}
}
//3、当做函数的参数
public class MyTest01 {
	public static void main(String[] args) {
		OutClass oc = new OutClass();
		oc.call2(new Inner(){
			public void speak(){
				System.out.println("打印吧这是一个匿名函数");
			}
		});
	}
}
class OutClass{
	public void call(){
		System.out.println("外部类");
	}
	public void newinner(){	
		Inner inte = new Inner(){
			public void speak(){
				System.out.println("这里是匿名内部类。");
			}
		};
		inte.speak();
	}
	public void call2(Inner ins){
		ins.speak();
	}
}
class Inner{
	public void speak(){
		System.out.println("内部类");
	}
}

15.API高级

常用API

API(Application Programming Interface)即应用程序接口,是一些预先定义的函数,或指软件系统不同组成部分衔接的约定。

应用程序接口又称为应用编程接口,是一组定义、程序及协议的集合,通过 API接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。API同时也是一种中间件,为各种不同平台提供数据共享。

学习一个新的API可以在API文档中学习。

##Object类

object是所有类的根类。是所有类的超类。所有类没有写继承什么类的时候默认继承object

//两个重要方法
//String toString();     返回值,参数列表,方法名。
	//输出一个对象默认输出一个对象的toString方法。
	//ctrl+鼠标点击类名,可以查看类的源码
	//哈希码值:一般指内存地址。
	//快速重写toString,右键source,生成toString方法。作为了解的方法一般用于调试,开发的时候很少用。
//代码
public class myObject001 {
	public static void main(String[] args) {
		Fire fire = new Fire();
		fire.toString();
	}
}
class Fire{
	String name;
	int age;
	String gender;
	@Override
	public String toString() {
		return "Fire [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}

}


//boolean equlals(Object obj);String中的equlals覆盖了object中的
	//比价两个对象是否相等。比较地址值是否相同。
//ctrl+shift+T搜索回车打开源码ctrl+O可以看到所有成员
//代码
@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Fire other = (Fire) obj;
		if (age != other.age)
			return false;
		if (gender == null) {
			if (other.gender != null)
				return false;
		} else if (!gender.equals(other.gender))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

finalize

垃圾回收的时候会调用这个方法

System类

###arraycopy

arraycopy(Object src,int srcPos,Object dest,int destPos, int length);

arraycopy(数组,索引起始位置,目标数组,目标数组的位置,复制数据长度);//两个数组都要提前创建,而且长度需要提前订好。复制长度并不设置数组长度,只表示赋值数据的长度,越界的话会报错。

public class myObject002 {
	public static void main(String[] args) {
		int[] array1 ={1,2,3,4,5,4,7,8,9,4};
		int[] array2 = new int[10];
 		System.arraycopy(array1, 0, array2,0,10);
 		for(int i = 0 ; i<10;i++){
 			System.out.print(array2[i]);
 		}
	}
}

currentTimeMillis

以毫秒值返回当前时间。值取决于底层系统时间。

这个毫秒的时间相对于1970年1月1日00:00:00

public class myObject002 {
	public static void main(String[] args) {
		long s = System.currentTimeMillis();
		System.out.println(s);
	}
}

###exit

终止java虚拟机:0表示正常非0表示异常。

public class myObject002 {
	public static void main(String[] args) {
		int[] array1 ={1,2,3,4,5,4,7,8,9,4};
		int[] array2 = new int[10];
 		System.arraycopy(array1, 0, array2,0,10);
 		for(int i = 0 ; i<10;i++){
 			if(i==5){
 				System.exit(0);
 			}
 			System.out.print(array2[i]);
 		}
	}
}

gc:了解就好

运行垃圾回收器。我们不调用虚拟机会自动调用

DATA类

在sql包下的data类,与数据库有关,但是今天学的是util包下的data,他们两个的关系是继承关系。

构造方法

​ Date();表示当前系统时间

​ Date(long date):根据基准时间过了long date毫秒后的日期。

public class myObject002 {
	public static void main(String[] args) {
		Date da = new Date();
		System.out.println(da);
		
      	long s = 5454544464L;
		Date ds = new Date(s);
		System.out.println(ds);
	}
}

####有用的方法:

1、毫秒值转化为date对象:

​ 设置方法。无返回值,需要参数,参数类型为long类型

​ setTime()

2、Date对象获取毫秒值

​ getTime();//输出的是毫秒值。

public class myObject002 {
	public static void main(String[] args) {
		Date da = new Date();
		System.out.println(da);//表示当前时间
      
		da.setTime(5656565L);//从1970年1月1日00:00:00开始向后增加5656565毫秒
		System.out.println(da);
      
      	System.out.println(da.getTime());//获取从基准时间到规定时间相差多少毫秒
	}
}

DateFormat类

DateFormat是一个抽象类,用于格式化日期的存在。想要使用DateFormat类中的方法可以使用静态方法和他的子类对象类调用。

DateFormat子类为SimpleDateFormat

SimpleDateFormat类

格式化:Data–>String

​ String format(Date date)

解析: String–>Data

​ parse(String source);

构造方法

​ simpleDateFormat();使用默认的默认的模式进行对象的创建。

​ SimpleDateFormat(String pattern);使用指定模式进行对象的构建。

shift+alt+m可以封装成一个方法。

//使用format把date类型的对象转化为String类型的对象。
public class myObject002 {
	public static void main(String[] args) {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		
		String s  = sdf.format(d);
		System.out.println(s);
		
	}
}
//使用String类型的对象转化为Date类型对象
public class myObject002 {
	public static void main(String[] args) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		
		String s  = sdf.format(d);
		System.out.println(s);
		
		Date b1 = sdf.parse(s);
		System.out.print(b1.toLocaleString());
	}
}



package com.itheima_04;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * SimpleDateFormat:
 * 		格式化:
 * 			Date --- String
 * 			2049-8-26 2049年8月26日
 * 			String format(Date date) 
 * 		解析:
 * 			String --- Date
 * 			"2049-8-26"
 * 			Date parse(String source) 
 * 
 * 构造方法:
 * 		SimpleDateFormat() :使用默认的模式进行对象的构建
 * 		SimpleDateFormat(String pattern) :使用的指定的模式进行对象的构建
 * 
 * 注意:Exception in thread "main" java.text.ParseException: Unparseable date: "49年9月26日  下午1:29"
 * 	    解析的字符串,模式必须和构建对象的模式一样
 *
 */
public class SimpleDateFormatDemo {
	public static void main(String[] args) throws ParseException {
		//method();
		//method2();
		//使用指定的模式进行对象的构建
		//1999年9月1日 10:10:10
		//4个小姨2个大美眉和2个小弟弟
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		
		//格式化
		Date date = new Date();
		String s = sdf.format(date);
		System.out.println(s);//2049年08月26日 13:39:12

		
		//解析
		Date d = sdf.parse("2049年08月26日 13:39:12");
		System.out.println(d.toLocaleString());
	}

	private static void method2() throws ParseException {
		//使用指定的模式进行对象的构建
		//1999年9月1日
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		//格式化
		Date date = new Date();
		String s = sdf.format(date);
		System.out.println(s);//2049年08月26日
		
		//解析
		Date d = sdf.parse("2049年08月26日");
		System.out.println(d.toLocaleString());
	}

	private static void method() throws ParseException {
		//使用默认模式进行对象的构建
		SimpleDateFormat sdf = new SimpleDateFormat();
		//创建日期对象
		Date date = new Date();
		
		//格式化 把日期对象转换成字符串
		String s = sdf.format(date);
		System.out.println(s);//49-8-26 下午1:29
		
		//解析 把字符串转换成日期对象
		Date d = sdf.parse("49年9月26日  下午1:29");
		System.out.println(d.toLocaleString());
	}

}

Calendar类

日历类。抽象类,不能创建对象,创建子类对象或者找找静态方法。

public class myObject002 {
	public static void main(String[] args) throws ParseException {
		Calendar cd = Calendar.getInstance();//初始化calendar对象
		cd.set(Calendar.DAY_OF_MONTH, 25);//set方法设置对应日期的值
		
		cd.add(Calendar.YEAR, 30);//add方法在给定日期的基础上加上值
		
		int year1 = cd.get(Calendar.YEAR);//get方法获取值。
		System.out.println(1);
		int year = cd.get(Calendar.YEAR);
		int month = cd.get(Calendar.MONTH) + 1;
		int day = cd.get(Calendar.DAY_OF_MONTH);
		
		System.out.println(year + "年" + month + "月" + day + "日");
	}

}

包装类

需求:判断一个数是否符合int类型的范围

由于基本数据类型只能做一些简单的操作和运算,所以Java为我们封装了基本数据类型,为每种基本数据类型提供了包装类

包装类就是封装了基本数据类型的类,为我们提供了更多复杂的方法和一些变量

byte Byte

short Short

char Character

int Integer

long Long

float Float

double Double

boolean Boolean

####Integer:

​ String — int

​ 方式1:int intValue()

​ 方式2: static int parseInt(String s)

​ int — String

​ 方式1: + “”

​ 方式2:String toString()

####构造方法:

​ Integer(int value)

​ Integer(String s)

//String --> int
//1、
Integer ig = new Integer("20");
System.out.println(ig);//返回int类型的数据
//2、
int as = ig.intValue();
System.out.println(as);
//3、
int b = Integer.parseInt("80");
System.out.println(b);

//int -->String
//1、
String i1 = ig.toString();
System.out.println(i1);
//2、
System.out.println(ig+"");
//3、
System.out.println(Integer.toString(ig));
拆箱和装箱
//自动装箱
//相当于: Integer i = new Integer(10);
//Integer i = 10;

//自动拆箱
//相当于 int a = i.intValue();
//Integer i = 10;
//int a = i;

#正则表达式

定义:一套规范可以用于匹配字符串。

方法:matches(String regex);判断是否匹配正则

public class myObject002 {
	public static void main(String[] args){
		String qq = "12a345";
		System.out.println(qq.matches("[1-9][0-9]{4,14}"));
	}

}

16.泛型和常见数据类型

集合体系结构

ArrayList<–List<–Collection

Collection是集合体系中的最顶层。

学习体系的时候先从最顶层开始学习,学习完成共性之后,在学习底层的使用。

Collection中包含的一些共性方法

boolean add(E e)

void clear()

boolean contains(Object o)

boolean isEmpty()

boolean remove(Object o)

int size()

Object[] toArray()

import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo01 {
	public static void main(String[] args) {
		Collection c = new ArrayList();
		
		c.add("caochen1");
		c.add("caochen2");
		c.add("caochen3");
		
//		c.clear();
//		boolean flag = c.contains("caochen1");
		boolean flag = c.remove("caochen1");
		
		int size = c.size();
		
		Object[] array = c.toArray();
		
		System.out.println(c);
		System.out.println(flag);
		System.out.println(size);
		System.out.println(array);	
	}
}

集合遍历方式

1、使用toArray(),转化为数组,然后遍历数组。

2、iterator(),返回一个迭代去对象,我们可以通过一个迭代器对象来遍历。next()方法返回下一个元素,没有元素返回的时候会报错。

public class CollectionDemo01 {
	public static void main(String[] args) {
		Collection c = new ArrayList();
		
		c.add("liji1");
		c.add("liji3");
		c.add("liji4");
		c.add("liji6");
		c.add("liji5");
		c.add("liji7");
		c.add("liji8");
		c.add("liji9");
		c.add("liji20");
		
		//集合遍历方法一:转化为数组
//		Object[] objs = c.toArray();
//		for (int i = 0; i < objs.length; i++) {
//			System.out.println(objs[i]);
//		}
		
		//方法二:使用迭代器
		Iterator it = c.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}
}

可以使用iterator的子类listiterator来添加东西。

不可以在集合添加会报错。因为迭代器是集合的副本,集合和迭代器不相同会报错。二操作迭代器集合会一起改变。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
 * 需求:判断集合中是否包含元素java,如果有则添加元素android
 * Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常
 * 迭代器是依赖于集合的,相当于集合的一个副本,当迭代器在操作的时候,如果发现和集合不一样,则抛出异常
 * 
 * 解决方案:
 * 		你就别使用迭代器
 * 		在使用迭代器进行遍历的时候使用迭代器来进行修改
 */
public class IteratorDemo3 {
	public static void main(String[] args) {
		//method();
		
		//创建集合对象
		//Collection c = new ArrayList();
		List c = new ArrayList();
		//添加元素
		c.add("hello");
		c.add("world");
		c.add("java");
		
		//我们可以通过遍历来获取集合中的每一个元素,然后进行比较即可
		/*Iterator it = c.iterator();
		while(it.hasNext()) {
			String s = (String)it.next();
			if(s.equals("java")) {
				c.add("android");
			}
		}*/
		
		ListIterator lit = c.listIterator();
		while(lit.hasNext()) {
			String s = (String)lit.next();
			if(s.equals("java")) {
				lit.add("android");
			}
		}
		System.out.println(c);
	}
	private static void method() {
		//创建集合对象
		Collection c = new ArrayList();
		//添加元素
		c.add("hello");
		c.add("world");
		c.add("java");
		//判断集合中是否包含元素java
		if(c.contains("java")) {
			c.add("android");
		}
		System.out.println(c);
	}
}

泛型

是一种广泛的类型,把明确数据类型的工作提前到了编译期间,借鉴了数组的特点。

/*
 * 使用集合存储自定义对象并遍历
 * 由于集合可以存储任意类型的对象,当我们存储了不同类型的对象,就有可能在转换的时候出现类型转换异常,
 * 所以java为了解决这个问题,给我们提供了一种机制,叫做泛型
 * 
 * 泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,借鉴了数组的特点
 * 泛型好处:
 * 			避免了类型转换的问题
 * 			可以减少黄色警告线
 * 			可以简化我们代码的书写
 * 
 * 什么时候可以使用泛型?
 * 		问API,当我们看到<E>,就可以使用泛型了
 * 			
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class CollectionDemo01 {
	public static void main(String[] args) {
		List<String> c = new ArrayList<String>();
		//添加元素
		c.add("河北");
		c.add("天津");
		c.add("上海");
		c.add("杭州");
		c.add("深圳");
		ListIterator<String> li = c.listIterator();
		li.add("河南");
		System.out.println(li);	
	}
}

foreach循环

格式

​ for(元素类型 变量:集合或者数组对象){

​ 可以直接使用变量

​ }

不能修改集合,否则会出现并发修改异常。

public class CollectionDemo01 {
	public static void main(String[] args) {
		List<String> c = new ArrayList<String>();
		//添加元素
		c.add("河北");
		c.add("天津");
		c.add("上海");
		c.add("杭州");
		c.add("深圳");
		
		ListIterator<String> li = c.listIterator();
		li.add("河南");
		
		for(String s : c){
			System.out.println(s);
		}
	}
}

常见数据结构

数组

import java.util.ArrayList;
import java.util.List;

/*
 * List:
 * 		有序的(存储和读取的顺序是一致的)
 * 		有整数索引
 * 		允许重复的
 * 
 * List的特有功能:
 * 			void add(int index, E element)  
 * 			E get(int index)  
 * 			E remove(int index)  
 *  		E set(int index, E element)
 *  
 *   增删改查
 

 *   
 */
public class ListDemo {
	public static void main(String[] args) {
		//创建的列表对象
		List list = new ArrayList();
		
		//void add(int index, E element)  : 在指定索引位置添加指定元素
		list.add(0, "hello");
		list.add(0, "world");
		list.add(1, "java");
		
		//E get(int index)  :根据索引返回元素
		/*System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(2));*/
		//System.out.println(list.get(3));
		
		/*for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}*/
		
		//E remove(int index)  : 删除指定元素并返回
		
		//System.out.println(list.remove(5));
		
		//E set(int index, E element) : 将指定索引位置的元素替换为指定元素,并将原先的元素返回
		System.out.println(list.set(0, "android"));
		
		System.out.println(list);
	}
}

链表

由链子连接在一起的一堆节点

节点:地址值,值下一个节点的地址值。

特点:

​ 查找慢,增删快

栈和队列

先进后出,手枪弹夹

队列

先进先出。排队买东西

#LinkedList

import java.util.LinkedList;

/*
 * List的常用子类:
 * 		ArrayList
 * 			底层是数组结构,查询快,增删慢
 * 		LinkedList
 * 			底层结构是链表,查询慢,增删快
 * 
 * 如何选择使用不同的集合?
 * 		如果查询多,增删少,则使用ArrayList
 * 		如果查询少,增删多,则使用LinkedList
 * 		如果你不知道使用什么,则使用ArrayList
 * 
 * LinkedList的特有功能:
 * 			void addFirst(E e)  
 * 			void addLast(E e) 
 			E getFirst()  
 			E getLast()  
 			E removeFirst() 
 			E removeLast() 
 * 				
 */
public class LinkedListDemo {
	public static void main(String[] args) {
			LinkedList list = new LinkedList();
			list.add("hello");
			list.add("world");
		
			//void addFirst(E e)  :将元素添加到索引为0的位置
 			//void addLast(E e) :将元素添加到索引为size()-1的位置
			list.addFirst("java");
			list.addLast("android");
			
 			//E getFirst()  :获取索引为0的元素
 			//E getLast()  :获取索引为size()-1的元素
			//System.out.println(list.getFirst());
			//System.out.println(list.getLast());
			
 			//E removeFirst() :删除索引为0的元素并返回
 			//E removeLast() :删除索引为size()-1的元素并返回
			System.out.println(list.removeFirst());
			System.out.println(list.removeLast());
			
			
			System.out.println(list);
	}
}
import java.util.ArrayList;
import java.util.List;

/*
 * 需求:定义一个方法,返回指定列表中指定元素的索引位置
 * 
 * 判断元素是否存在
 * 
 */
public class ListTest {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("hello");
		list.add("world");
		list.add("java");
		
		//int index = index(list,"php");
		//System.out.println(index);
		
		//boolean flag = contains(list, "php");
		//System.out.println(flag);
		
		boolean flag = list.contains("php");
		System.out.println(flag);
	}
	
	public static int index(List list,Object other) {
		for(int x = 0;x < list.size();x++) {
			//获取列表中的元素
			Object obj = list.get(x);
			//使用列表中的元素和指定的元素进行比较
			if(obj.equals(other)) {
				return x;
			}
		}
		//查找不到指定的元素
		return -1;
	}
	
	public static boolean contains(List list,Object other) {
		//获取指定元素在指定列表中的索引位置
		int index = index(list,other);
		//如果索引位置大于等于0,则认为元素存在,否则不存在
		if(index >= 0) {
			return true;
		}
		else {
			return false;
		}
	}	
}

17.MAP与Set集合

HashSet是Collection的子孙类。HashSet是Set的子类。他间接的实现了祖先类的所有方法。

集合

遍历集合有三种方式,

​ 转数组

​ 迭代器

​ 增强for

public class HashSetDemo {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("hello");
		set.add("world");
		set.add("java");
		
		//第一种遍历方法,转成数组
		Object[] ob = set.toArray();
		for(int i=0 ; i<ob.length;i++){
			System.out.println(ob[i]);
		}
		
		//迭代器
		Iterator<String> it = set.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		//增强for循环
		for(String s : set){
			System.out.println(s);
		}
	}
}

Set集合的小特点:

1、无序

2、不能重复

3、没有索引

使用hashset来存储自定义对象并遍历

public class HashSetDemo2 {
	public static void main(String[] args) {
		HashSet<Student> hs = new HashSet<Student>();
		Student s1 = new Student("张三",87);
		Student s2 = new Student("例子",99);
		Student s3  = new Student("张三",87);
		hs.add(s1);
		hs.add(s2);
		hs.add(s3);
		
		for (Student student : hs) {
			System.out.println(student);
		}
	}
}
class Student{
	String name;
	int age;
	public Student(String name , int age){
		this.name = name;
		this.age  = age;
		
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}

通过查看源码发现hashset的方法首先会

使用当前集合中的每一个元素和新添加的元素进行hash进行比较。

如果hash值不一样则添加新的元素。

如果hash值一样比较地址值或者使用equals进行比较,比较结果一样则认为结果重复不添加。

所有比较结果都一样则添加。

去除对象重复

public class HashSetDemo2 {
	public static void main(String[] args) {
		HashSet<Student> hs = new HashSet<Student>();
		Student s1 = new Student("张三",87);
		Student s2 = new Student("例子",99);
		Student s3  = new Student("张三",87);
		hs.add(s1);
		hs.add(s2);
		hs.add(s3);
		
		for (Student student : hs) {
			System.out.println(student);
		}
	}
}
class Student{
	String name;
	int age;
	public Student(String name , int age){
		this.name = name;
		this.age  = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
	@Override
	public int hashCode() {
		
		return 1;
	}
	
	@Override
	public boolean equals(Object obj) {
		Student s = (Student)obj;
		if(!this.name.equals(s.name)){
			return false;
		}
		if(this.age!=s.age){
			return false;
		}
		return true;
	}
	+
}

Collections

collections与collection有什么区别

​ collection是集合体系的最顶层。包含了集合体系的共性。

​ collections是一个工具类,不需要创建对象。方法全是static修饰的。方法用于操作collection的

public class HashSetDemo3 {
	public static void main(String[] args) {
		List<String> l = new ArrayList<String>();
		l.add("asdf");
		l.add("fasdf");
		l.add("asdfasdf");
		l.add("asdfaasdfasdf");
		//Collections.swap(l, 0, 3);
		//Collections.reverse(l);
		//int index = Collections.binarySearch(l, "asdf");

		
		
//		List<String> dest = new ArrayList<String>();
//		dest.add("");
//		dest.add("");
//		dest.add("");
//		dest.add("");
//		Collections.copy(dest,l);
		
		
		
		//Collections.fill(l, "halsdjflkasdjkfjasdlfjlkasdjflkjsdlkfjlkasdjflkasdjflkjljsdfk");
		//Collections.shuffle(l);把列表内的元素随机打乱顺序。
//		Collections.sort(l);从小到大排序
		System.out.println(l);
	}
}

模拟斗地主

public class HashSetDemo01 {
	public static void main(String[] args) {
		String[] arry1= {"黑桃","红桃","梅花","方片"};
		String[] arry2 ={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
		
		ArrayList<String> box = new ArrayList<String>();
		for (int i = 0; i < arry1.length; i++) {
			for (int j = 0; j < arry2.length; j++) {
				box.add(arry1[i]+arry2[j]);
			}
		}
		box.add("大王");
		box.add("小王");
		
		Collections.shuffle(box);

		System.out.println(box);
		
		
		
		ArrayList<String> a = new ArrayList<String>();
		ArrayList<String> b = new ArrayList<String>();
		ArrayList<String> c = new ArrayList<String>();
		for(int i =0 ; i<box.size()-3;i++){
			if(i%3 == 0){
				a.add(box.get(i));
			}
			if(i%3 == 1){
				b.add(box.get(i));
			}
			if(i%3 == 2){
				c.add(box.get(i));
			}
		}
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
		for(int i=box.size()-3;i<box.size();i++){
			System.out.println(box.get(i));
		}
		
	}
}

有对应关系的存储MAP

相当于python里面的字典。

map是一个,创建实例需要使用子类

put方法在遇到重复的key的时候返回存在key的value值,然后替换当前键值对。

判断是否存在相应的东西

​ containsKey

​ containsValue

clear();清空所有的键值对

remove();删除指定键值对,按key查找。返回value值。

isEmpty():判断是否有对应关系。

size();返回有键值对的数量

get():通过key获取value值。

public class MapDemo01 {
	public static void main(String[] args) {
		Map<String,String> m = new  HashMap<String,String>();
		m.put("ID001", "game");
		m.put("ID002", "TVgame");
		m.put("ID003", "GalGame");
		
//		m.clear();//清空所有键值对
//		System.out.println(m.containsKey("ID001"));
//		System.out.println(m.containsValue("game"));
//		System.out.println(m.remove("ID001"));
//		System.out.println(m.isEmpty());
//		System.out.println(m.size());
//		System.out.println(m.get("ID001"));
		
		System.out.println(m);
	}
}

第一种遍历方法

public class MapDemo02 {
	public static void main(String[] args) {
		Map<String,String> m = new HashMap<String,String>();
		m.put("1","2");
		m.put("2","3");
		m.put("3","4");
		m.put("4","5");
		m.put("5","6");
		m.put("6","7");
		
		Set<String> set = m.keySet();
		for(String s1:set){
			System.out.println(m.get(s1));
		}
		
	}
}

第二种遍历方法

Map<String,String> map = new HashMap<String,String>();
map.put("1","2");
map.put("3","4");
map.put("5","6");
Set<Map.Entry<String,String>> entrys = nmap.entrySet();
for (Map.Entry<String,String> entry: entrys){
  String key = entry.getKey();
  String value = entry.getValue();
  System.out.println(key+value);
}

18.异常处理

异常:

定义:写代码的时候出现的编译或者运行时候的错误。

异常处理:

jvm(java虚拟机)帮我们处理异常的方法:

​ 在控制台输出抛出的异常错误信息。

​ 终止程序运行。

所有异常的超类:Throwable

​ 子类:Error:出现了不能处理的错误。

​ 子类:Exception:出现了能够处理的错误。

两种处理方法:

1、自己处理异常:
//先捕获,后处理:
//try......catch语句。

try{
	有可能出现问题的代码。
}
catch(抛出异常的类型  参数){
	处理异常的方法。				
}
2、抛出异常:

​ 当我们不想处理异常,或者没有能力处理异常的时候我们就可以选择抛出异常。谁调用方法,谁处理异常。入口main方法抛出异常,虚拟机来处理。

//使用throws在方法声明的地方抛出异常。
public static void function() throws  IOException{
	FileWriter fw = new FileWriter("a.txt");
}
//执行顺序:发现异常不执行下面的代码。直接执行catch语句里面。没有异常不会执行catch

如何处理多个异常

​ 使用try…catch…catch…语句来处理过个异常。

public class ErrorDemo01 {
	public static void main(String[] args) {
		FileWriter fw=null;
		try{
			fw = new FileWriter("a.txt");
			fw.write("awesdf");
			fw.write("asdlkfjlasjdf");
			System.out.print(2/0);
			fw.write("asdfaklsdjflkajs");
			fw.write("faskdjflkasdjf");
		}catch(Exception as){
			as.printStackTrace();
		}catch(AbstractMethodError as){
			as.printStackTrace();
		}
		finally{
			try {
				if(fw!=null)
				{
					fw.close();
				}
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
	}
}

catch中的异常处理方法:

​ getMessage();//获取原因

​ toString();//类型和原因

​ printStackTrace();//类型原因和位置。

和虚拟机不同的是:虚拟机处理会中断程序,但是我们处理就不会中断程序运行。

public class ThrowDemo01 {
	public static void main(String[] args) throws IOException {
		try{
			System.out.println(2/0);
		}catch(ArithmeticException ae){
			ae.printStackTrace();
		}
		System.out.println("aslkdjflkjasd");
		function();
	}
	public static void function() throws  IOException{

		FileWriter fw = new FileWriter("a.txt");
	}

}

finally

无论catch里面的代码是否执行,finally里面的代码一定会执行的。

例如用于释放资源之类的。

public class ErrorDemo01 {
	public static void main(String[] args) {
		FileWriter fw=null;
		try{
			fw = new FileWriter("a.txt");
			fw.write("awesdf");
			fw.write("asdlkfjlasjdf");
			fw.write("asdfaklsdjflkajs");
			fw.write("faskdjflkasdjf");
		}catch(Exception as){
			as.printStackTrace();
		}finally{
			try {
				if(fw!=null)
				{
					fw.close();
				}
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
	}
}

thorows:把异常交给处理人

throw:制造异常的方式,并且结束方法。

​ 运行时期扔runtimeException的子类或者本类

​ 编译时期异常扔Exception及其子类对选哪个。但是不能是runtimeException对象。

注意:

​ 1、抛出的是编译时期异常必须在方法上面抛出。throws

​ 2、字符串设置为null再调用length变量会报错。空指针异常。可以使用过个try…catch语句,其实一个try可以跟多个catch。多个catch之间可以有子父类关系。父类放到子类异常的下面。

创建自己的异常:

​ 继承一个异常,然后写一个无参构造,再写一个有字符串的构造。

制造异常throw,创建异常并抛出

public class ErrorDemo01 {
	public static void main(String[] args) {
		FileWriter fw=null;
		try{
			throw new MyError("你失败了吧哈哈哈");
			
		}catch(MyError as){
			as.printStackTrace();
		}
		finally{
			System.out.print("你失败了");
		}
	}
	
}
class MyError extends RuntimeException{

	public MyError() {
		super();
		// TODO Auto-generated constructor stub
	}

	public MyError(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}
	
}

递归

把大问题拆成许多小问题,然后把小问题拆成更多的小问题。把更多小问题解决的时候我们就解决完成了大问题。

递归会在内存中积压。

public class MyDebug01 {
	public static void main(String[] args) {
		System.out.print(digui(5));
	}
	public static int digui(int n){
		if(n==1 || n==2){
			return 1;
		}
		else{
			return digui(n-2)+digui(n-1);
		}
	}
}

19.IO流高级

File类

文件和目录路径名的抽象表现形式,File类的实例是不可变的。

构造方法

File(String pathname);//将指定的路径名转化为File对象。

​ 指向不存在的路径不会报错,也不会创建文件。

File(File parent,String child);//根据指定父路径的对象和文件路径创建对象。

File(String parent,String child);//根据指定的父路径和文件路径来创建File对象。

##File常用功能

创建功能:

​ boolean createNewFile()//指定文件不存在成功,存在失败。

​ boolean mkdir()//文件夹存在不成功,不存在成功

​ boolean mddirs()//创建多级目录,指定路径存在不成功,不存在成功。创建的到底是什么东西,是使用方法决定的。

删除功能:

​ boolean delete()//删除文件或者文件夹,并返回true,删除的时候路径删掉的是最后一级。不能删除多级目录。删除文件夹下不能有文件和子文件夹。delete删除的时候不走回收站。

获取功能:

​ File getAbsoluteFile()

​ String getAbsolutePath()

​ String getName()

​ String getParent()

​ File getParentFile()

​ String getPath()

​ long lastModified() 最后一次被修改的时间

​ long length()

判断功能:

​ boolean exists()

​ boolean isAbsolute()

​ boolean isDirectory()

​ boolean isFile()

​ boolean isHidden()

修改功能:

​ boolean renameTo(File dest);

绝对路径:(省略)

参照路径:(省略)

创建和删除功能
public class MyFIle01 {
	public static void main(String[] args) throws IOException {
//		File file = new File("a");
//		file.createNewFile();
		
//		File file = new File("b");
//		file.mkdir();
		
//		File file = new File("c\\d\\e\\f\\g");
//		file.mkdirs();
		
		File file = new File("c");
		System.out.println(file.delete());
	}
}
判断功能
public class MyFile02 {
	public static void main(String[] args) {
		//exists();
		File file = new File("a");
		System.out.println(file.exists());
		
		File file1 = new File("d");
		System.out.println(file1.exists());
		
		//isAbsolute()
		File file2 = new File("F:\\JAVA\\day05\\workspace\\myFileDemo02");
		System.out.println(file2.isAbsolute());
		

		File file3 = new File("myFileDemo02");
		System.out.println(file3.isAbsolute());
		
		//isDirectory()
		File file4= new File("b");
		System.out.println(file4.isDirectory());
		
		File file5 = new File("a");
		System.out.println(file5.isDirectory());
		
		//isFile()
		
		File file6= new File("b");
		System.out.println(file6.isFile());
		
		File file7 = new File("a");
		System.out.println(file7.isFile());
		
		//isHidden()判断文件是否被隐藏
		File file8= new File("b");
		System.out.println(file8.isFile());
		
	}
}	
获取和修改功能
public class MyFile03 {
	public static void main(String[] args) {
//		File f1 = new File("a.txt");
//		System.out.println(f1.getAbsoluteFile());
//		
//		File f2 = new File("b.txt");
//		System.out.println(f2.getAbsolutePath());
//		
//		File f3 = new File("c.txt");
//		System.out.println(f3.getName());//可以获取文件名字和文件夹名字。
		
//		File f4 = new File("F:\\JAVA\\day05\\workspace\\myFileDemo02","d.txt");
//		System.out.println(f4.getParent());
//		
//		File f5 = new File(new File("F:\\JAVA\\day05\\workspace\\myFileDemo02"),"d.txt");
//		System.out.println(f5.getParent());
//		

//		File f6 = new File("F:\\JAVA\\day05\\workspace\\myFileDemo02","d.txt");
//		System.out.println(f6.getParentFile());
//		
//		File f7 = new File("d.txt");
//		System.out.println(f7.getPath());
//		
//		File f8 = new File("b");
//		System.out.println(f8.lastModified());
//		Date date = new Date(1565918223901L);
//		System.out.println(date.toLocaleString());
		
//		File f9 = new File("a");
//		System.out.println(f9.length());
		
		File f10 = new File("a");
		File f11 = new File("b.txt");
		f10.renameTo(f11);
		
	}
}
重要的获取功能
//String[] list()
//File[] listFiles()
//static File[] listRoots()

public class MyFile04 {
	public static void main(String[] args) {
//		File f1 = new File("c:\\");
//		String[] s = f1.list();
//		for(String a : s){
//			System.out.println(a);
//			
//			
//		File f2 = new File("c:\\");
//		File[] s1 = f2.listFiles();
//		for(File a2 : s1){
//			System.out.println(a2);
//		}
		
//		File[] a = File.listRoots();
//		for(File r3:a){
//			System.out.println(r3);
//		}
	}
}
遍历所有目录
public class MyFile05 {
	public static void main(String[] args) {
		File fs = new File("F:\\JAVA\\day05\\workspace\\myFileDemo02");
		digui(fs);
	}
	public static void digui(File file){
		File[] f = file.listFiles();
		for(File f1 : f){
			if(f1.isDirectory()){
				digui(f1);
			}else if(f1.isFile()){
				System.out.println(f1.getName());
			}
		}
	}
}
删除指定的目录:
//先把所有子目录和子文件都删掉。然后把本身目录删掉
import java.io.File;

public class MyFile06 {
	public static void main(String[] args) {
		File f = new File("F:\\a");
		method(f);
	}
	public static void method(File file){
		File[] files = file.listFiles();
		for(File f : files){
			if(f.isDirectory()){
				method(f);
				System.out.println(f.getName());
				f.delete();
				
			}else if(f.isFile()){
				System.out.println(f.getName());
				f.delete();
			}
		}
		file.delete();
	}
}

IO流分类

分类方式

​ 流向分类:

​ 输入流:Reader FileReader

​ 输出流:Writer FileWriter

​ 数据类型:

​ 字节流:

​ 字节输入流:InputStream

​ 字节输出流:OutputStream

​ 字符流:

​ 字符输入流:Reader

​ 字符输出流:Writer

字符流能做的,字节流都可以做,但是反过来不行。

字符流复制文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

//使用IO操作来复制文件,针对字符流文件
public class MyIOTest {
	public static void main(String[] args) throws IOException {
//		FileReader fr = new FileReader("copy.txt");
//		FileWriter fw = new FileWriter("copy3.txt");
		
		//第一种方法,使用单个字符读取
//		int ch;
//		while((ch=fr.read())!=-1){
//			fw.write(ch);
//		}
		
		//第二种方法使用一个数组读取
//		char[] chs = new char[1024];
//		int len;
//		while((len = fr.read(chs))!=-1){
//			System.out.print(len);
//			System.out.print(new String(chs,0,len));
//			fw.write(chs,0,len);
//		}
		
		
		
		
		//第三种方法使用缓冲字符流读取单个字符
//		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
//		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy4.txt"));
//		int ch;
//		while((ch=bfr.read())!=-1){
//			bfw.write(ch);
//		}
//		bfr.close();
//		bfw.close();
//		
		
		
		//第四种方法使用缓冲字节流读取一个数组
//		
//		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
//		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy5.txt"));
//		
//		char[] chs = new char[1024];
//		int len;
//		
//		while((len=bfr.read(chs))!=-1){
//			bfw.write(chs,0,len);
//		}
//		bfr.close();
//		bfw.close();
		
		
		//第五种方法,使用缓冲字节流读取字符串
		BufferedReader bfr =new BufferedReader(new FileReader("copy.txt"));
		BufferedWriter bfw  = new BufferedWriter(new FileWriter("copy6.txt"));
		
		String str;
		while(((str = bfr.readLine()) !=  null )){
			bfw.write(str);
			bfw.newLine();
			bfw.flush();
		}
		bfr.close();
		bfw.close();
//		
//		fr.close();
//		fw.close();
	}
}

字节流复制文件

public class MyIODemo01 {
	public static void main(String[] args) throws IOException {
		
		FileInputStream fr = new FileInputStream("b.txt");
		FileOutputStream fs = new FileOutputStream("d.txt");
		
//		byte[] by= new byte[1024];
//		int len;
//		while((len=fr.read(by))!=-1){
//			fs.write(by,0,len);
//		}
		int by ;
		while((by=fr.read())!=-1){
			fs.write(by);
		}
		fs.close();
		fr.close();
	}
}

20.字符流与字节流

标准输入和输出流

System.in;//标准输入流、InputStream类型

System.out;//标准输出流,PrintStream类型是OutputStream类行的子类。

//把代码输出到控制台。
public class MyIODemoStream {
	public static void main(String[] args) throws IOException {
		//创建读取对象
		BufferedReader br = new BufferedReader(new FileReader("MyFile02.java"));
		//创建输出对象
		OutputStream os =System.out;
		
		String line;
		while((line = (br.readLine()))!=null){
			os.write(line.getBytes());
			os.write("\r\n".getBytes());
		}
		//释放资源
		br.close();
		os.close();
	}
}

把字节输出流转化为字符输出流OutputStreamWriter();

//第二种方法
public class MyIODemoStream {
	public static void main(String[] args) throws IOException {
		//创建读取对象
		BufferedReader br = new BufferedReader(new FileReader("MyFile02.java"));
		//创建输出对象
//		OutputStream os =System.out;
		
		BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(System.out));
		
		String line;
		while((line = (br.readLine()))!=null){
			bw.write(line);
			bw.write("\r\n");
		}
		//释放资源
		br.close();
		bw.close();
	}
}

把字节输入流转化为字符输出流InputStreamReader();

public class InputStreamReaderDemo {
	public static void main(String[] args) throws IOException {
		Reader r = new InputStreamReader(System.in);
		FileWriter fw = new FileWriter("a.txt");
		
		int len;
		char[] b = new char[1024];
		while((len = r.read(b))!=-1){
			fw.write(b,0,len);
			fw.flush();
		}
		r.close();
		fw.close();
	}
}

打印流

PrintStream

PrintWriter

注意:只能输出不能输入。

功能

自动换行:使用println()方法

自动刷新:在打开自动换行的开关的情况下。使用println等三个函数会自动刷新。

public class MyIOStreamDemo01 {
	public static void main(String[] args) throws IOException {
		PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
		pw.println("mysun");
		pw.write("hello");
		pw.close();
	}
}	

字符打印流复制文件

public class MyIOStreamDemo02 {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("MyFile02.java"));
		PrintWriter pw = new PrintWriter(new FileWriter("c.txt"),true);
		String line;
		
		while((line = br.readLine())!=null){
			pw.println(line);
		}
		br.close();
		pw.close();
	}
}

对象操作流

ObjectOutputStream:对象输出流。

ObjectInputStream:对象出入流。

注意:

​ 使用对象输入流读取对象只能使用对象输出流来写。

​ 只能将java.io.Serializable接口的对象写入流中。

标识接口,没有方法,当一个对象需要IO流进行读写的时候这个类必须实现该接口。

//对象输出流和对象输入流进行对象的读写
package com.itheima;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class MyIOStreamDemo03 {
	public static void main(String[] args) throws IOException, IOException {
		//method();
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d.txt"));
		
		try{
			while(true){
				System.out.println(ois.readObject());
			}
		}catch(Exception as){
			System.out.println("已经读取完毕");
		}
		
		ois.close();
	}

	@SuppressWarnings("unused")
	private static void method() throws IOException, FileNotFoundException {
		ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("d.txt"));
		
		Student s1 = new Student("kasdf",454);
		Student s2 = new Student("asdfasdf",78997);
		
		oos.writeObject(s1);
		oos.writeObject(s2);
		
		oos.close();
	}
}

如果写入了类,对象。但是后来改变了类中的一些结构,然后在读取的时候就会报错。

​ 报错为:

报错原因有三种:

解决方法:把类的编号固定、不随着成员改变而改变。

ctrl+1;产生一个固定的编号。

Properties

双列集合。实现了map接口。

同步的安全性高,但是效率低。键和值都是String格式。

public class MyIOStreamDemo01 {
	public static void main(String[] args) throws IOException {
		Properties pt = new Properties();
		pt.put("ID001", "asdf");
		pt.put("ID002", "asdfasdfas");
		pt.put("ID003", "asdfasdf");
		PrintWriter pw = new PrintWriter(new FileWriter("e.txt"),true);
		pw.println("mysun");
		pw.write("hello");
		pt.list(pw);
		pw.close();
	}
}

编码表

ANSI本地编码表:跟你的系统有关。

java中的默认是ANSI(gbk)

21.多线程

多线程

进程:当前正在运行的程序,一个应用程序在内存中的执行区域。

线程:进程中的一个执行控制单元,执行路径。一个进程可以有一个进程,也可以有多个线程。

​ 单线程:安全性高,效率低。

​ 多线程:同时做多个事情,安全性低,效率高。

Thread

实现Runnable接口(非常重要的接口)

创建多线程的方法:

​ 创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的
run 方法。接下来可以分配并启动该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:

启动一个线程会执行run里面的方法。

CPU执行线程是随机的。多个程序高速随机切换。

//创建实例
MyThread mt = new MyThread();
//修改线程名字
mt.setName("老王");
//启动
mt.start();

//创建实例1
MyThread mt1 = new MyThread();
//启动2
mt1.start();

//getName();获取该类的名字。setName(String name);

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run
方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

 class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

 PrimeRun p = new PrimeRun(143);
     new Thread(p).start();

static void sleep(long millis):当前线程睡一会

多线程模拟火车票售票出现问题的原因及解决方法。

//synchronized(同步,锁)修饰的线程和代码块一旦被某个线程访问则直接锁住。其他线程将无法访问。
//格式

synchronized(锁对象){
  
}注意:锁对象需要被所有线程锁共享。

synchronized修饰方法;同步方法也有锁对象默认为this。
静态同步方法默认对象是字节码对象。

同步可以提高稳定性,但是效率低了。

线程的生命周期

生命周期:一个对象的生老病死。

22.网络编程

//首先创建发送端Socket对象(创建连接),需要IP和端口号
//收到数据都是通过管道(IO流),发送数据
//获取输出流对象
//发送数据
//释放资源
//Socket是基于TCP的。

//客户端
public class MyTCPSend {
	public static void main(String[] args) throws IOException {
		//创建套接字对象
		Socket s = new Socket(InetAddress.getByName("192.168.207.1"),10086);
		//创建输出流
		OutputStream os = s.getOutputStream();
		//创建数据
		String s1 = "hello world!!!!!!!!!!!";
		os.write(s1.getBytes());
		

		//释放资源
		s.close();
	}
}
//服务端
/*
 * 创建接收端Socket对象
 * 监听(阻塞)
 * 获取输入流对象
 * 获取数据
 * 输出数据
 * 释放资源
 */
 public class MyTCPReceive {
	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(10086);
		Socket s = ss.accept();
		
		InputStream is = s.getInputStream();
		
		byte[] byt= new byte[1024];
		int len;
		len = is.read(byt);
		System.out.println(new String (byt,0,len));
		s.close();
		ss.close();
	}
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值