Java高级
抽象类和抽象方法
1.定义
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。
类的设计应该保证父类和子类都能够共享特征。
有时候将一个父类设计的非常抽象,以至于他都没有具体的实例,这样的类叫做抽象类。
优势:不能被实例化
2.abstract修饰类:抽象类
抽象类不能实例化
抽象类中一定有构造器,便于子类实例化时调用(涉及:子类实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象使用,完成相关操作。
3.abstract修饰方法:抽象方法
抽象方法只有方法的声明,没有方法体。
包含抽象方法的类,一定是一个抽象方法,然而,抽象类中可以没有抽象方法。
若子类重写类父类中的所有方法后,此子类方可实例化。
若子类没有重写父类中的所有方法抽象方法,
则此子类也是一个抽象类,需要使用abstract修饰该子类。
4.abstract关键字的注意事项
abstract不能用来修饰:属性、构造器等结构。
abstract不能用来修饰私有方法、静态方法、final修饰的方法。
接口
接口的特性:
属性:需要public static final修饰
方法:要求public abstract
没有构造方法,也没有程序块
接口不能创建对象,子类多实现接口来做事
接口也是一种引用数据类型
接口是完全抽象的。(抽象类是半抽象的)或者说,接口是特殊的抽象类。
接口和抽象类的相同点和不同点
可以实现多个接口,不能继承多个类
final关键字
final可以声明类、属性、方法
final标记的类不能被继承(final和abstract不能同时存在),没有子类
final标记的基本数据类型不能被改变//public void func(final int i){i++;}会报错
final标记的引用数据类型是可以改变其属性的(不改变引用数据类型的地址,不能new)//public void func(final Object o){o.i++;}
final标记的方法不能被重写,可以重载
final标记的标量是常量,一般public static final double Pi=3.14,常量可以被私有(goto 和 const在java中是关键字,但不过被使用,这种叫做保留关键字)
枚举
枚举指的是一组固定的常量组成的类型
类型安全:取值只能在涌现的范围内选择
public enum Season {
Spring("春天","春意盎然"),
Summer("夏天","夏日炎炎"),
;
private String seasonName;
private String seasonDesc;
Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public void setSeasonName(String seasonName) {
this.seasonName = seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
public void setSeasonDesc(String seasonDesc) {
this.seasonDesc = seasonDesc;
}
}
public class TestSeason {
public static void main(String[] args) {
Season spring = Season.Spring;
System.out.println(spring.getSeasonName()+"---"+spring.getSeasonDesc());
}
}
异常
谁调用,谁处理
异常处理的五个关键字
捕获异常:try/catch/finally
抛出异常:throw 可以手动抛出异常对象;例如throw new Exception("异常信息")
声明异常:throws 声明方法 可能要抛出的各种异常了,向上传递异常,直到Main函数 保证程序可以正常运行
returnType methodName(...) throws Exception{
throw new Exception("异常信息");
}
运行时异常RuntimeException
Exception---------------------------------------------------------异常层次结构的根类
ArithmeticException--------------------------------------------算术错误情形,如 以零作为除数
ArrayIndexOutOfExceptionBoundsException------------数组下标越界
NullPointerException-------------------------------------------尝试访问null对象成员
NumberFormatException-------------------------------------数字格式转换异常,如 把"abc"转换成数字
检查异常CheckException:检查异常是程序员必须进行处理
何时需要自定义异常
当JDK中的异常不能满足程序需要的时候
自定义异常
public class MyException extends Exception{//自定义异常
private int errorCode;//异常编码
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public MyException() {
}
public MyException(int errorCode,String msg) {
super(msg);
this.errorCode = errorCode;
}
}
public static void main(String[] args) {
System.out.println("请输入1~3之间的任何一个数:");
Scanner input = new Scanner(System.in);
try{
int num=input.nextInt();
if (num==1){
System.out.println("课程1");
}else if (num==2){
System.out.println("课程2");
}else if(num==3){
System.out.println("课程3");
}else {
System.out.println("输入错误,输入的数不在1~3之间");
}
}catch (Exception e){
System.out.println("输出错误,发生异常");
}finally {
System.out.println("欢迎提出建议");
}
}
public class Item07 {
private int age;
public void setAge(int age) throws MyException{
if (age<=100&&0<=age){
this.age=age;
}else {
throw new MyException(1001,"年龄必须在1到100岁之间");
}
}
public static void main(String[] args) {
Item07 item07 = new Item07();
try {
item07.setAge(101);
} catch (MyException e) {
System.out.println("异常编码:"+e.getErrorCode()+"异常信息:"+e.getMessage());
}
}
}
注解
内置的注解
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
作用在代码的注解是
-
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
-
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
-
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(或者说 元注解)是:
-
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
-
@Documented - 标记这些注解是否包含在用户文档中。
-
@Target - 标记这个注解应该是哪种 Java 成员。
-
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
从 Java 7 开始,额外添加了 3 个注解:
-
@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
-
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
-
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
自定义注解
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int age() default 20;
}
import java.lang.annotation.Annotation;
public class Person {
@Deprecated
private String name;
@MyAnnotation(age = 16)
private int age;
public void sayHi(){
}
@MyAnnotation(age = 16)
public void setAge(){
}
public void checkAge() throws NoSuchFieldException, NoSuchMethodException {
//通过反射加载Person类,并获取名为"age"的属性下的所有注解
// Annotation[] annotations = Person.class.getDeclaredField("age").getAnnotations();//getField("age").getAnnotations();
Annotation[] annotations = Person.class.getMethod("setAge").getAnnotations();
//遍历输出
for (Annotation a : annotations) {
if (a instanceof MyAnnotation){//找到自定义注解
if (((MyAnnotation)a).age()<18){//读取注解中的年龄信息,并进行判断
System.out.println("未成年");
}else {
System.out.println("具备选举权");
}
}
}
}
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Person person = new Person();
person.checkAge();
}
}
内部类
内部类与外部类的关系
1.成员内部类的创建需要依赖于外部类对象(成员方法必须用过对象调用),在没有外部类实例之前无法创建成员内部类对象
2.内部类与外部类相对独立,不是is a关系
3.私有属性的相互访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问
4.创建内部类的语法
在外部类内部创建内部类对象Inner inner = new Inner();
在外部类外部创建内部类对象,外部类.内部类 inner=new Outer().new Inner();
5.在内部类内部使用隐藏的外部类对象,外部类类名.this
内部类的优势
内部类不受外部类是否继承各类,是多重继承的完美解决方案,是对JAVA单一继承的有益补充
内部类的分类
静态内部类
使用static修饰,类比静态方法,不需要外部类对象产生就内使用
不能访问外部类的成员域,只能访问静态域
创建语法
1.外部类内部:与成员内部类一样
2.外部了外部:Inner inner=new Outer.Inner();
非静态内部类
对外部完全隐藏,因此方法内部类不能用任何的访问修饰符
方法内部类没有访问形参,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final
匿名内部类
1.必须继承一个抽象类或者实现一个接口
2.没有构造方法
反射
在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用
基于Class类
Class类是Java反射机制的起源和入口,每个类都有自己的Class对象,用于获取与类相关的各种信息,提供了获取信息的相关方法,Class类继承自Object类
优点
提高了Java程序的灵活性和扩展性,降低了耦合性
问题
可读性较差,反射会模糊程序内部逻辑
主要使用到的类
Class类---可获取类与类的成员信息
Field类---可访问类的属性
Method类---可调用类的方法
Constructor类---可调用类的构造方法
使用反射机制的一般步骤
1.通过反射加载类(三种方式)
//第一种:对象名.getClass();
Student student = new Student("jack", 10);
Class aClass=student.getClass();
//第二种:类名.class;
Class aClass = Student.class;
//第三种:Class.forName("加载类的所在路径")
Class aClass = Class.forName("com.cx.demo.Student");
2.通过反射创建对象(两种方式)
Class aClass = Class.forName("com.cx.demo.Student");
//1.调用无参数的构造方法
Student student =(Student) aClass.newInstance();//创建一个实例
//2.调用指定构造方法getDeclaredFields(指定构造方法对应参数的数据类型)
Constructor con = aClass.getDeclaredConstructor(String.class,int.class);
Student ton = (Student)con.newInstance("ton", 23);//创建一个实例
3.通过反射操作属性
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();//属性是对象的一部分
//getDeclaredFields():所有属性,包括私有的
Field[] declaredFields = clazz.getDeclaredFields();
//getDeclaredField("属性名"):指定属性
Field name = clazz.getDeclaredField("name");
//stu.setName设置属性值
name.setAccessible(true);//使得可以获取私有属性 如果是private属性,必须设置为true
name.set(stu,"张三");
4.通过反射动态执行方法
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();
//1.得到方法getDeclaredMethod("方法名",方法所带参数的数据类型)
Method show = clazz.getDeclaredMethod("show", String.class);
//2.动态调用方法invoke(所属对象,传入的参数)
show.invoke(stu,"反射太麻烦了");
//所有的方法,不包括过构造方法
Method[] declaredMethods = aClass.getDeclaredMethods();
几个常用的工具类
时间转换类
SimpleDateFormat
使用方法
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
//"2022-10-18"-->Date
public static void main(String[] args) {
String str = "2022-10-18";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(str);//String--->Date
System.out.println(date);
String format = sdf.format(date);//Date---->String
System.out.println(format);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
工具类案例
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
//日期格式
private static final String pattern="yyyy-MM-dd";
private static final SimpleDateFormat sdf=new SimpleDateFormat(pattern);
//将字符串转换成日期
public static Date convertToDate(String str) throws Exception{
Date date=null;
date=sdf.parse(str);
return date;
}
//将日期转换字符串
public static String convertToString(Date date){
String str=null;
str=sdf.format(date);
return str;
}
}
日历
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String dataStr = simpleDateFormat.format(now);
System.out.println("今天的日期是"+dataStr);
System.out.println("今天的日期是"+now);
Calendar calendar=Calendar.getInstance();
System.out.println(calendar);
System.out.println(calendar.getTime());
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));//0是一月,少一个月
System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//星期天是第一天
calendar.add(Calendar.MONTH,1);
System.out.println("一个月后:"+calendar.getTime());
}
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TestCalendar {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
Calendar calendar=Calendar.getInstance();
calendar.set(2012,4,6);
System.out.println(simpleDateFormat.format(calendar.getTime())+"是一年中的第"+calendar.get(Calendar.WEEK_OF_YEAR)+"星期");
}
}
字符串
public class item02 {
public static void main(String[] args) {
String str="hello";
String num="12345";
String str1= new String("good");
System.out.println(str.length());//长度
抽象类和抽象方法
1.定义
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。
类的设计应该保证父类和子类都能够共享特征。
有时候将一个父类设计的非常抽象,以至于他都没有具体的实例,这样的类叫做抽象类。
优势:不能被实例化
2.abstract修饰类:抽象类
抽象类不能实例化
抽象类中一定有构造器,便于子类实例化时调用(涉及:子类实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象使用,完成相关操作。
3.abstract修饰方法:抽象方法
抽象方法只有方法的声明,没有方法体。
包含抽象方法的类,一定是一个抽象方法,然而,抽象类中可以没有抽象方法。
若子类重写类父类中的所有方法后,此子类方可实例化。
若子类没有重写父类中的所有方法抽象方法,
则此子类也是一个抽象类,需要使用abstract修饰该子类。
4.abstract关键字的注意事项
abstract不能用来修饰:属性、构造器等结构。
abstract不能用来修饰私有方法、静态方法、final修饰的方法。
接口
接口的特性:
属性:需要public static final修饰
方法:要求public abstract
没有构造方法,也没有程序块
接口不能创建对象,子类多实现接口来做事
接口也是一种引用数据类型
接口是完全抽象的。(抽象类是半抽象的)或者说,接口是特殊的抽象类。
接口和抽象类的相同点和不同点
可以实现多个接口,不能继承多个类
final关键字
final可以声明类、属性、方法
final标记的类不能被继承(final和abstract不能同时存在),没有子类
final标记的基本数据类型不能被改变//public void func(final int i){i++;}会报错
final标记的引用数据类型是可以改变其属性的(不改变引用数据类型的地址,不能new)//public void func(final Object o){o.i++;}
final标记的方法不能被重写,可以重载
final标记的标量是常量,一般public static final double Pi=3.14,常量可以被私有(goto 和 const在java中是关键字,但不过被使用,这种叫做保留关键字)
枚举
枚举指的是一组固定的常量组成的类型
类型安全:取值只能在涌现的范围内选择
public enum Season {
Spring("春天","春意盎然"),
Summer("夏天","夏日炎炎"),
;
private String seasonName;
private String seasonDesc;
Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public void setSeasonName(String seasonName) {
this.seasonName = seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
public void setSeasonDesc(String seasonDesc) {
this.seasonDesc = seasonDesc;
}
}
public class TestSeason {
public static void main(String[] args) {
Season spring = Season.Spring;
System.out.println(spring.getSeasonName()+"---"+spring.getSeasonDesc());
}
}
异常
谁调用,谁处理
异常处理的五个关键字
捕获异常:try/catch/finally
抛出异常:throw 可以手动抛出异常对象;例如throw new Exception("异常信息")
声明异常:throws 声明方法 可能要抛出的各种异常了,向上传递异常,直到Main函数 保证程序可以正常运行
returnType methodName(...) throws Exception{
throw new Exception("异常信息");
}
运行时异常RuntimeException
Exception---------------------------------------------------------异常层次结构的根类
ArithmeticException--------------------------------------------算术错误情形,如 以零作为除数
ArrayIndexOutOfExceptionBoundsException------------数组下标越界
NullPointerException-------------------------------------------尝试访问null对象成员
NumberFormatException-------------------------------------数字格式转换异常,如 把"abc"转换成数字
检查异常CheckException:检查异常是程序员必须进行处理
何时需要自定义异常
当JDK中的异常不能满足程序需要的时候
自定义异常
public class MyException extends Exception{//自定义异常
private int errorCode;//异常编码
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public MyException() {
}
public MyException(int errorCode,String msg) {
super(msg);
this.errorCode = errorCode;
}
}
public static void main(String[] args) {
System.out.println("请输入1~3之间的任何一个数:");
Scanner input = new Scanner(System.in);
try{
int num=input.nextInt();
if (num==1){
System.out.println("课程1");
}else if (num==2){
System.out.println("课程2");
}else if(num==3){
System.out.println("课程3");
}else {
System.out.println("输入错误,输入的数不在1~3之间");
}
}catch (Exception e){
System.out.println("输出错误,发生异常");
}finally {
System.out.println("欢迎提出建议");
}
}
public class Item07 {
private int age;
public void setAge(int age) throws MyException{
if (age<=100&&0<=age){
this.age=age;
}else {
throw new MyException(1001,"年龄必须在1到100岁之间");
}
}
public static void main(String[] args) {
Item07 item07 = new Item07();
try {
item07.setAge(101);
} catch (MyException e) {
System.out.println("异常编码:"+e.getErrorCode()+"异常信息:"+e.getMessage());
}
}
}
注解
内置的注解
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
作用在代码的注解是
-
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
-
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
-
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(或者说 元注解)是:
-
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
-
@Documented - 标记这些注解是否包含在用户文档中。
-
@Target - 标记这个注解应该是哪种 Java 成员。
-
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
从 Java 7 开始,额外添加了 3 个注解:
-
@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
-
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
-
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
自定义注解
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int age() default 20;
}
import java.lang.annotation.Annotation;
public class Person {
@Deprecated
private String name;
@MyAnnotation(age = 16)
private int age;
public void sayHi(){
}
@MyAnnotation(age = 16)
public void setAge(){
}
public void checkAge() throws NoSuchFieldException, NoSuchMethodException {
//通过反射加载Person类,并获取名为"age"的属性下的所有注解
// Annotation[] annotations = Person.class.getDeclaredField("age").getAnnotations();//getField("age").getAnnotations();
Annotation[] annotations = Person.class.getMethod("setAge").getAnnotations();
//遍历输出
for (Annotation a : annotations) {
if (a instanceof MyAnnotation){//找到自定义注解
if (((MyAnnotation)a).age()<18){//读取注解中的年龄信息,并进行判断
System.out.println("未成年");
}else {
System.out.println("具备选举权");
}
}
}
}
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Person person = new Person();
person.checkAge();
}
}
内部类
内部类与外部类的关系
1.成员内部类的创建需要依赖于外部类对象(成员方法必须用过对象调用),在没有外部类实例之前无法创建成员内部类对象
2.内部类与外部类相对独立,不是is a关系
3.私有属性的相互访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问
4.创建内部类的语法
在外部类内部创建内部类对象Inner inner = new Inner();
在外部类外部创建内部类对象,外部类.内部类 inner=new Outer().new Inner();
5.在内部类内部使用隐藏的外部类对象,外部类类名.this
内部类的优势
内部类不受外部类是否继承各类,是多重继承的完美解决方案,是对JAVA单一继承的有益补充
内部类的分类
静态内部类
使用static修饰,类比静态方法,不需要外部类对象产生就内使用
不能访问外部类的成员域,只能访问静态域
创建语法
1.外部类内部:与成员内部类一样
2.外部了外部:Inner inner=new Outer.Inner();
非静态内部类
对外部完全隐藏,因此方法内部类不能用任何的访问修饰符
方法内部类没有访问形参,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final
匿名内部类
1.必须继承一个抽象类或者实现一个接口
2.没有构造方法
反射
在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用
基于Class类
Class类是Java反射机制的起源和入口,每个类都有自己的Class对象,用于获取与类相关的各种信息,提供了获取信息的相关方法,Class类继承自Object类
优点
提高了Java程序的灵活性和扩展性,降低了耦合性
问题
可读性较差,反射会模糊程序内部逻辑
主要使用到的类
Class类---可获取类与类的成员信息
Field类---可访问类的属性
Method类---可调用类的方法
Constructor类---可调用类的构造方法
使用反射机制的一般步骤
1.通过反射加载类(三种方式)
//第一种:对象名.getClass();
Student student = new Student("jack", 10);
Class aClass=student.getClass();
//第二种:类名.class;
Class aClass = Student.class;
//第三种:Class.forName("加载类的所在路径")
Class aClass = Class.forName("com.cx.demo.Student");
2.通过反射创建对象(两种方式)
Class aClass = Class.forName("com.cx.demo.Student");
//1.调用无参数的构造方法
Student student =(Student) aClass.newInstance();//创建一个实例
//2.调用指定构造方法getDeclaredFields(指定构造方法对应参数的数据类型)
Constructor con = aClass.getDeclaredConstructor(String.class,int.class);
Student ton = (Student)con.newInstance("ton", 23);//创建一个实例
3.通过反射操作属性
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();//属性是对象的一部分
//getDeclaredFields():所有属性,包括私有的
Field[] declaredFields = clazz.getDeclaredFields();
//getDeclaredField("属性名"):指定属性
Field name = clazz.getDeclaredField("name");
//stu.setName设置属性值
name.setAccessible(true);//使得可以获取私有属性 如果是private属性,必须设置为true
name.set(stu,"张三");
4.通过反射动态执行方法
Class clazz = Class.forName("com.cx.demo.Student");
Student stu = (Student) clazz.newInstance();
//1.得到方法getDeclaredMethod("方法名",方法所带参数的数据类型)
Method show = clazz.getDeclaredMethod("show", String.class);
//2.动态调用方法invoke(所属对象,传入的参数)
show.invoke(stu,"反射太麻烦了");
//所有的方法,不包括过构造方法
Method[] declaredMethods = aClass.getDeclaredMethods();
几个常用的工具类
时间转换类
SimpleDateFormat
使用方法
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
//"2022-10-18"-->Date
public static void main(String[] args) {
String str = "2022-10-18";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(str);//String--->Date
System.out.println(date);
String format = sdf.format(date);//Date---->String
System.out.println(format);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
工具类案例
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
//日期格式
private static final String pattern="yyyy-MM-dd";
private static final SimpleDateFormat sdf=new SimpleDateFormat(pattern);
//将字符串转换成日期
public static Date convertToDate(String str) throws Exception{
Date date=null;
date=sdf.parse(str);
return date;
}
//将日期转换字符串
public static String convertToString(Date date){
String str=null;
str=sdf.format(date);
return str;
}
}
日历
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String dataStr = simpleDateFormat.format(now);
System.out.println("今天的日期是"+dataStr);
System.out.println("今天的日期是"+now);
Calendar calendar=Calendar.getInstance();
System.out.println(calendar);
System.out.println(calendar.getTime());
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));//0是一月,少一个月
System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//星期天是第一天
calendar.add(Calendar.MONTH,1);
System.out.println("一个月后:"+calendar.getTime());
}
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TestCalendar {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
Calendar calendar=Calendar.getInstance();
calendar.set(2012,4,6);
System.out.println(simpleDateFormat.format(calendar.getTime())+"是一年中的第"+calendar.get(Calendar.WEEK_OF_YEAR)+"星期");
}
}
字符串
public class item02 {
public static void main(String[] args) {
String str="hello";
String num="12345";
String str1= new String("good");
System.out.println(str.length());//长度
System.out.println(str.charAt(2));//取字符
System.out.println(str.indexOf("l"));//取字符下标
System.out.println(str.concat(str1));//拼接
System.out.println(str.substring(3, 5));//(]
}
}
import java.util.Scanner;
public class Item05 {
public static void main(String[] args) {
char c;
String str;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
str=scanner.next();
System.out.println("请输入要查找的字符");
c=scanner.next().charAt(0);
if (str.indexOf(c)>-1){
int count=0;
for (int i = 0; i < str.length(); i++) {
if (c==(str.charAt(i))){
count++;
}
}
System.out.println(str+"中包含"+count+"个"+c);
}else {
System.out.println(str+"中不存在"+c);
}
}
}
public class Item06 {
public static void main(String[] args) {
String s = new String();
StringBuffer stringBuffer = new StringBuffer("1234556");
//千位分隔符
for (int i = stringBuffer.length() - 3; i > 0; i -= 3) {
stringBuffer.insert(i, ",");
}
System.out.println(stringBuffer);
}
}
I/O流


操作文件
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) {
File dir=new File("/tmp/Temp/temp");
File file = new File(dir,"text.txt");
if (!dir.exists()){
dir.mkdir();//创建目录
}
if (!file.exists()){//判断文件是否存在
try {
file.createNewFile();//创建文件
} catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println(file.getPath());
System.out.println(file.getName());
file.delete();//删除文件
dir.delete();//删除目录
}
System.out.println(file.exists());
}
}
使用FileInputStream读取文件
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
File dir = new File("/tmp/Temp/temp");
File file = new File("/tmp/Temp/temp/test.txt");
if (!dir.exists()) {
dir.mkdir();//新建目录
}
if (!file.exists()) {
try {
file.createNewFile();//新建文件
} catch (IOException e) {
e.printStackTrace();
}
}
//读取文件
try {
FileInputStream fileInputStream = new FileInputStream(file);
int num = fileInputStream.read();//一次读取一个字节
System.out.println(num);
int contentLength;
byte[] bytes= new byte[1024];
String content=null;
//超过1kb
while ((contentLength = fileInputStream.read(bytes))!=-1){
content=new String(bytes,0,contentLength);//转化成字符串
}
System.out.println(content);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用FileOutputStream写文件
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileWriteDemo {
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/good.txt");
String msg="weekend";
byte[] bytes=msg.getBytes(StandardCharsets.UTF_8);
fileOutputStream.write(bytes,0,bytes.length);//写文件
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedReader和FileReader读取文件
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferReaderDemo {
public static void main(String[] args) {
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader("/tmp/Temp/temp/test.txt"));
// int read = bufferedReader.read();//再次读取有可能丢失首字母
// System.out.println(read);
//按行读取
// String readLine = null;
// while ((readLine = bufferedReader.readLine()) != null) {
// System.out.println(readLine);
// }
//读取十个字符
// char[] chars = new char[10];
// int length = bufferedReader.read(chars, 0, chars.length);
// System.out.println(length);
// System.out.println(new String(chars,0,length));
//超过十个字符
// char[] chars = new char[10];
// int length=0;
// while ((length=bufferedReader.read(chars,0,chars.length))!=-1){
// System.out.println(new String(chars,0,length));
// }
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedWriter和FileWriter写文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferWriterDemo {
public static void main(String[] args) {
try {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("/tmp/Temp/temp/new.txt"));
bufferedWriter.write("first line");
bufferedWriter.newLine();//换行
bufferedWriter.write("second line");
bufferedWriter.newLine();
bufferedWriter.flush();//清楚空余
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化与反序列化
import java.io.*;
public class ObjectDemo {
public static void main(String[] args) {
// Student student = new Student("jack",20);
try {
//对象的序列化
// FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/student.bin");
// ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//
// objectOutputStream.writeObject(student);
// objectOutputStream.close();
// fileOutputStream.close();
//反序列化
FileInputStream fileInputStream = new FileInputStream("/tmp/Temp/temp/student.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Student student = (Student) objectInputStream.readObject();
System.out.println(student);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
泛型
public interface Person<T> {
T getName();
void setName(T t);
}
public class Student<T> implements Person{
private T t;
public Student() {
}
public Student(T t) {
this.setName(t);
}
public void show(T t){
System.out.println(t.getClass().getName());
System.out.println(t);
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
@Override
public T getName() {
return this.t;
}
@Override
public void setName(Object o) {
this.t= (T) o;
}
public static void main(String[] args) {
// Student<String> student=new Student<>();
// student.show("jack");
Student<String> student = new Student<>("张三");
System.out.println(student.getName());
System.out.println(student.getT().getClass().getName());
}
}
多线程
进程:系统运行的基本单位,有独立的内存空间和系统资源
线程:进程中执行运算的最小单位,处理机分配给线程,即真正在处理机上运行的是线程
线程的创建的两种方式
继承java.lang.thread类
实现java.lang.Runnable接口(还是要借助于thread启动)
1.定义线程
2.创建线程对象
3.启动线程
4.终止线程(不推荐手动终止)
cpu会随机执行里面的线程:主线程,自定义线程
线程的声明周期包括四个状态:新生状态,可运行状态,阻塞状态和死亡状态
多个线程处于可运行的状态(线程调度)
分配优先级 1的优先级最高,默认值是5,Thread.currentThread().getPriority()
更改优先级 new Thread().setPriority(4)
new Thread().join()添加进阻塞进程
Thread.sleep(500)当前线程停止执行,进入不可运行状态(阻塞),其他等待运行的进程机会是相等的
yield当前线程转入暂停运行的状态(不阻塞),如果没有其他等待执行的线程,当前线程会马上恢复执行,会优先级相同的或更高的执行
线程同步
关键字synchronized
同步方法
同步代码块
线程通信
wait()挂起当前线程,并释放共享资源的锁
notify()在因调用该对象的wait方法二阻塞的线程中随机选择一个解除阻塞,但要等到获得锁后才可以正真执行
notifyall将因调用该对象的wait方法而阻塞的所有线程一次性全部解除阻塞
这三个方法只能在同步方法或者同步代码块中使用
线程创建
//1.定义线程:通过继承的方式
public class MyThread extends Thread{
//重写run
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
public static void main(String[] args) {
//cpu会随机执行里面的线程:主线程,自定义线程
//2.创建线程对象
MyThread myThread = new MyThread();
//3.启动线程
myThread.setName("我的线程");//定义线程名
myThread.start();
//主线程
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
// MyRun myRun = new MyRun();
// new Thread(myRun,"自定义线程名").start();//Thread才是真正的线程
//
// //主线程
// for (int i = 0; i < 5; i++) {
// //当前运行的是哪个线程
// System.out.println(Thread.currentThread().getName()+":"+i);
// }
//优先级只是cpu执行该线程的一个重要参考要素之一
MyRun myRun = new MyRun();
Thread t1 = new Thread(myRun, "线程1");
Thread t2 = new Thread(myRun, "线程2");
t1.setPriority(4);
t2.setPriority(6);
t1.start();
// t2.start();
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
}
}
分苹果
public class ShareApple implements Runnable {
private int count = 5;//苹果的总数
private boolean flag = true;//标记位,是否可以拿苹果
//拿苹果的方法
//同步方法
public synchronized boolean getApple() {
// synchronized (this) {//同步代码块
if (count == 0)//是否有苹果
return false;
count--;
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count >= 0) {
System.out.println(Thread.currentThread().getName() + "成功拿到了一个苹果,还剩" + count + "个苹果");
} else {
System.out.println(Thread.currentThread().getName() + "没有拿到苹果");
}
return true;
// }
}
@Override
public void run() {
while (flag)
flag = getApple();
if (count == 0) {
System.out.println(Thread.currentThread().getName() + "线程结束");
}
}
}
public class TestApple {
public static void main(String[] args) {
ShareApple shareApple = new ShareApple();
new Thread(shareApple,"小明").start();
new Thread(shareApple,"小黑").start();
}
}
存取款
public class Account {
private int balance = 500;
public int getBalance() {
return balance;
}
public void qu(int atm) {
balance -= atm;
}
}
public class TestAccount implements Runnable {
private Account account = new Account();
@Override
public void run() {
for (int i = 0; i < 4; i++) {
makeWithDraw(100);
if (account.getBalance() < 0)
System.out.println("账户透支");
}
}
private void makeWithDraw(int atm) {
synchronized (account) {
if (account.getBalance() >= atm) {
System.out.println(Thread.currentThread().getName() + "\t准备取款!");
account.qu(atm);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"\t完成取款");
}else {
System.out.println("余额不足以支付\t"+Thread.currentThread().getName()+"\t取款的余额为"+account.getBalance());
}
}
}
public static void main(String[] args) {
TestAccount testAccount = new TestAccount();
Thread p1 = new Thread(testAccount, "张三");
Thread p2 = new Thread(testAccount, "张三的妻子");
p1.start();
p2.start();
}
}
生产者消费者模式
public class Consumer extends Thread {//消费者
private ShareData data;
Consumer(ShareData data) {
this.data = data;
}
@Override
public void run() {
char s;
do {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
s = data.getChar();
} while (s != 'D');
}
}
public class Producer extends Thread {
private ShareData data;
Producer(ShareData data) {
this.data = data;
}
@Override
public void run() {
//专门生产
for (char i = 'A'; i <= 'D'; i++) {
data.produce(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ShareData {
private char c;
private boolean flag = false;//信号量
//生产资源
public synchronized void produce(char c) {
while (flag) {
try {
System.out.println("生产资源:消费者还没有消费,需要等待消费者进行消费");
wait();//线程立即挂起,释放锁和cpu资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
notify();
this.c = c;
System.out.println("生产资源:生产者已经生产了产品" + c + ",等待消费者消费");
}
//消费资源
public synchronized char getChar() {
while (!flag) {
try {
System.out.println("消费资源:生产者还没有生产,无法消费消费。。。");
wait();//线程立即挂起,释放锁和cpu资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = false;
notify();
System.out.println("消费资源:消费者消费了产品" + c + "通知生产者生产");
return c;
}
}
public class TestConsumer {
public static void main(String[] args) {
ShareData data = new ShareData();
new Producer(data).start();
new Consumer(data).start();
//定义了两个线程:每一次 都来争夺cpu资源
}
}
死锁
public class DeadLockRunnable implements Runnable {
//编号
public int num;
//资源
private static Object chopsticks1 = new Object();
private static Object chopsticks2 = new Object();
private boolean flag =false;//信号量
/**
* num = 1 拿到chopsticks1 等待chopsticks2
* num = 2 拿到chopsticks2 等待chopsticks1
*/
@Override
public void run() {
if (num==1){
System.out.println(Thread.currentThread().getName()+"拿到了chopsticks1,等待chopsticks2");
synchronized (chopsticks1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (chopsticks2){
System.out.println(Thread.currentThread().getName()+"用餐完毕");
}
}
}
else if (num==2){
System.out.println(Thread.currentThread().getName()+"拿到了chopsticks2,等待chopsticks1");
synchronized (chopsticks2){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (chopsticks1){
System.out.println(Thread.currentThread().getName()+"用餐完毕");
}
}
}
}
}
public class DeadLockTest {
public static void main(String[] args) {
DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
deadLockRunnable1.num=1;
DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
deadLockRunnable2.num=2;
new Thread(deadLockRunnable1,"张三").start();
new Thread(deadLockRunnable2,"李四").start();
}
}
线程通信
客户端与服务端
InetAddress类 无构造方法 getLocalHost获取本地ip getByName获取网络主机名
基于tcp:Socket(客户端)和Server Socket(服务器端)
ServerSocket.accept():获取客户端socket
Socket通信模型
进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
两个Socket类的构造方法及其含义
Socket socket=new Socker("localhost",8800)
ServerSocket serverSocket = new ServerSocket(9000);
socket.getOutputStream();
os.write
1.建立连接
2.打开Socket关联的输入输出流
3.数据流中读写信息
4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {//客户端
//创建Socket
Socket socket = new Socket(InetAddress.getLocalHost(),9000);
//得到输出流
OutputStream os = socket.getOutputStream();
//写入字符串
// String msg="你好,服务器端,这是用户登录信息";
// os.write(msg.getBytes(StandardCharsets.UTF_8));
//写入对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(os);
User user = new User("Jack","123");
objectOutputStream.writeObject(user);
//告诉服务器,消息发完了
socket.shutdownOutput();
//得到输入流
InputStream is = socket.getInputStream();
//读取信息
byte[] by = new byte[1024];
int len ;//= is.read(by);
String content=null;
//超过1kb
while ((len=is.read(by))!=-1){
content=new String(by,0,len);
}
System.out.println("客户端发送的信息是:"+content);
//告诉服务器,消息发完了
// socket.shutdownOutput();
//关闭
is.close();
os.close();
socket.close();
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class MyServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建的是ServerSocket,指定对应的端口号
System.out.println("服务器请求链接");
ServerSocket serverSocket = new ServerSocket(9000);
//2.等待链接
Socket socket = serverSocket.accept();
System.out.println("服务器等待链接");
//3.得到输入流,其实就是客户端的输出流
InputStream is = socket.getInputStream();
//4.1读取字符串信息
// byte[] by = new byte[1024];
// int len;//= is.read(by);
// String content = null;
// //超过1kb
// while ((len = is.read(by)) != -1) {
// content = new String(by, 0, len);
// }
// System.out.println("客户端发送的信息是:" + content);
//4.2读取对象
ObjectInputStream ois = new ObjectInputStream(is);
User user = (User) ois.readObject();
String msg2=null;
if ("123".equals(user.getPassword())){
msg2="欢迎你"+user.getUsername();
}else {
msg2="用户名或密码错误";
}
System.out.println(msg2);
//得到输出流,对客户端进行响应
OutputStream os = socket.getOutputStream();
String msg = "你好,客户端,信息已经收到";
//writer
os.write(msg.getBytes(StandardCharsets.UTF_8));
//5.关闭资源
is.close();
os.close();
socket.close();
serverSocket.close();
}
}
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
服务器端与多客户端
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class LoginServer {//多线程处理客户端
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9000);
Socket socket;
System.out.println("服务器等待请求。。。。");
while (true) {//实现一直监听
socket = serverSocket.accept();
System.out.println("服务器接收到请求");
//多线程
LoginThread thread = new LoginThread(socket);
thread.start();
}
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class LoginClient1 {
public static void main(String[] args) throws IOException {
User user = new User("张三", "123");
Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("我是客户端1,给服务器发送登录信息。。。");
oos.writeObject(user);
//告诉服务已经发送完了消息
socket.shutdownOutput();
//接收服务器的信息
byte[] temp = new byte[1024];
int len = is.read(temp);
System.out.println("服务器的响应"+new String(temp,0,len));
socket.close();
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class LoginClient2 {
public static void main(String[] args) throws IOException {
User user = new User("李四", "123");
Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("我是客户端2,给服务器发送信息");
oos.writeObject(user);
//告诉服务已经发送完了消息
socket.shutdownOutput();
//接收服务器的信息
byte[] temp = new byte[1024];
int len = is.read(temp);
System.out.println("服务器的响应"+new String(temp,0,len));
socket.close();
}
}
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class LoginThread extends Thread {
private Socket socket;
public LoginThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//处理客户端请求
try (//写在小括号里会自动关闭资源close
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ObjectInputStream ois = new ObjectInputStream(is);
) {
//得到客户端的信息
User user = (User) ois.readObject();
//给客户端回信息
String msg = null;
if (user == null) {
msg = "没有发送登录信息,登录失败";
} else {
msg = "欢迎你" + user.getUsername();
}
System.out.println(msg);
os.write(msg.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
网络编程
ip地址与主机名
C类地址(192.0.0.0-223.255.255.0):192.168.0.0~192.168.255.255
InetAddress类 无构造方法 getLocalHost获取本地ip getByName获取网络主机名
基于tcp:Socket(客户端)和Server Socket(服务器端)
ServerSocket.accept():获取客户端socket
Socket通信模型
进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
两个Socket类的构造方法及其含义
Socket socket=new Socker("localhost",8800)
ServerSocket serverSocket = new ServerSocket(9000);
socket.getOutputStream();
os.write
1.建立连接
2.打开Socket关联的输入输出流
3.数据流中读写信息
4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestAddress {
public static void main(String[] args) throws UnknownHostException {
//InetAddress:IP地址包装类
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.getHostAddress());//ip地址
System.out.println(localHost.getHostName());//主机名
//得到网络主机名
InetAddress address = InetAddress.getByName("www.baidu.com");
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
}
}
UDP
基于UDP协议的Socket编程
1.利用DatagramSocket发送数据包
2.利用DatagramPacket对象封装数据包
3.利用DataGramPacket处理数据包
4.利用DataGramPacket接收数据包
建立发送端,接收端
创建数据
建立数据包
调用Socket的发送接收方法
关闭SOcket
发送端与接收端是两个独立运行的程序
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
public class UDPSend {//发送端
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
byte[] msg = "最新的邮件来了。。。。".getBytes(StandardCharsets.UTF_8);
//创建数据包,即将发送出去的数据包,发送的内容,收获的ip,端口号,
DatagramPacket dp = new DatagramPacket(msg, 0, msg.length, InetAddress.getByName("localhost"), 9000);
//发送数据
ds.send(dp);
//关闭资源:socket
ds.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDPReceive {
public static void main(String[] args) throws IOException {//接收端
//1.创建DatagramSocket
DatagramSocket ds = new DatagramSocket(9000);
//2.创建Packet
byte[] temp = new byte[1024];
DatagramPacket dp = new DatagramPacket(temp, temp.length);
//3.接收数据
ds.receive(dp);
//发送方的主机名
String hostName = dp.getAddress().getHostName();
//发送方的端口号
int port = dp.getPort();
System.out.println("发送方的主机名是"+hostName+"发送方的端口号是"+port);
byte[] bytes = dp.getData();//获取接收到的内容
String msg=new String(bytes,0, dp.getLength());
System.out.println("发送过来的信息是:"+msg);
//4.关闭资源
ds.close();
}
}
DOM文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student id="1">
<name>王同</name>
<class>java</class>
<score>89</score>
</student>
<student id="2">
<name>李佳</name>
<class>sql</class>
<score>58</score>
</student>
<student id="3">
<name>李白</name>
<class>python</class>
<score>90</score>
</student>
</students>
<!ELEMENT students (student+)> <!ELEMENT student (name,class,score)> <!ATTLIST student id CDATA #IMPLIED> <!ELEMENT name (#PCDATA)> <!ELEMENT class (#PCDATA)> <!ELEMENT score (#PCDATA)>
public class TestXML {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
//1.得到document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//2.解析和加载xml文件到内存中去
Document document = documentBuilder.parse("student.xml");
//3.返回文档中的所有子节点
NodeList nodeList = document.getChildNodes();
Node root = nodeList.item(nodeList.getLength() - 1);
System.out.println("root:" + root.getNodeName());//students
//4.再查找他的子节点
NodeList childNodes = root.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if ("student".equals(item.getNodeName())) {
NodeList nodes = item.getChildNodes();
for (int j = 0; j < nodes.getLength(); j++) {
Node node = nodes.item(j);
if ("name".equals(node.getNodeName())) {
System.out.println("name:" + node.getTextContent());
} else if ("class".equals(node.getNodeName())) {
System.out.println("class:" + node.getTextContent());
} else if ("score".equals(node.getNodeName())) {
System.out.println("score:" + node.getTextContent());
}
}
}
}
}
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;
public class UpdateXML {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException {
//使用DOM对XML文件进行数据修改
//1.得到document
DocumentBuilderFactory dbf;
dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//解析和加载xml文件到内存中去
Document document = documentBuilder.parse("student.xml");
//1.删除某个节点
// NodeList list = document.getElementsByTagName("student");
// for (int i = 0; i < list.getLength(); i++) {
// Element item = (Element)list.item(i);
// //node:节点(文本节点),element:元素
// //凡是元素都是节点,但是节点不一定都是元素,例如:一个单纯的回车也是节点
//// System.out.println(item.getAttribute("id"));
// if ("2".equals(item.getAttribute("id"))){
// item.getParentNode().removeChild(item);
// }
// }
//2.添加节点
// //student(name class score)
// Element student = document.createElement("student");
// student.setAttribute("id", "3");//设置属性值
// //name
// Element stuName = document.createElement("name");//创建节点
// stuName.setTextContent("李白");//设置节点内容
// student.appendChild(stuName);//添加节点
// //class
// Element stuClass = document.createElement("class");
// stuClass.setTextContent("python");
// student.appendChild(stuClass);
// //score
// Element stuScore = document.createElement("score");
// stuScore.setTextContent("90");
// student.appendChild(stuScore);
// //找到根节点students
// NodeList nodeList = document.getElementsByTagName("students");
// Node students = nodeList.item(nodeList.getLength() - 1);
// students.appendChild(student);
//修改:李白-》李清照
//1.查找节点
NodeList student3 = document.getElementsByTagName("student");
for (int i = 0; i < student3.getLength(); i++) {
Element item = (Element)student3.item(i);
if ("3".equals(item.getAttribute("id"))){
Node name = item.getElementsByTagName("name").item(0);
//2.修改节点内容
name.setTextContent("李清照");
break;
}
}
//保存成XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
// 设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
StreamResult result = new StreamResult(new FileOutputStream("student.xml"));
// 把DOM树转换为XML文件
transformer.transform(domSource, result);
}
}
DOM4j
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="book1">
<name>三国演义</name>
<price>99.88</price>
</book>
<book id="book2">
<name>西游记</name>
<price>77.88</price>
</book>
<book id="book3">
<name>李白的诗</name>
<price>88.88</price>
</book>
</books>
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.Iterator;
import java.util.List;
public class TestDom01 {
public static void main(String[] args) throws DocumentException {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
System.out.println(root.getName());//root
//遍历显示所有的数据
List<Element> list = root.elements("book");
for (Element book:list){
Attribute id = book.attribute("id");
System.out.println("id:"+id.getValue());
//迭代器
Iterator<Element> it = book.elementIterator();
while (it.hasNext()){
Element element = it.next();
System.out.println(element.getName()+":"+element.getText());
}
System.out.println("----------------");
}
}
}
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class TestDom02 {
public static void main(String[] args) throws DocumentException, IOException {
//需求:实现 删除 id="book3"这样的一个节点
/*
<book id="book">
<name>李白的诗</name>
<price>88.88</price>
</book>
*/
//解析xml文件
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
//找到相应的节点
List<Element> bookList = root.elements("book");
for (Element book:bookList){
Attribute id = book.attribute("id");
if ("book3".equals(id.getValue())){
book.getParent().remove(book);//删除
}
}
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("删除成功");
}
}
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class TestDom03 {
public static void main(String[] args) throws DocumentException, IOException {
//需求:实现 新增节点
/*
<book id="book">
<name>李白的诗</name>
<price>88.88</price>
</book>
*/
//解析xml文件
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
//新增节点
Element book = DocumentHelper.createElement("book");
book.addAttribute("id", "book3");
Element name = DocumentHelper.createElement("name");//创建节点
name.setText("李白的诗");//设置属性
book.add(name);//添加节点
Element price = DocumentHelper.createElement("price");
price.setText("88.88");
book.add(price);
root.add(book);
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("新增成功");
}
}
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
public class TestDom04 {
public static void main(String[] args) throws DocumentException, IOException {
//需求 实现 修改 id="book3"这样的一个节点 李白的诗-》李清照的诗句2.外部类外部:StaticInnerClass.Inner inne
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
System.out.println(root.getName());//root
//遍历所有的数据
List<Element> list = root.elements("book");
for (Element book : list) {
//找到对应的节点
if ("book3".equals(book.attribute("id").getValue())) {
//迭代器
Iterator<Element> it = book.elementIterator();
while (it.hasNext()) {
Element element = it.next();
//找到要修改的文本
if ("李白的诗".equals(element.getText())) {
element.setText("李清照的诗");
System.out.println(element.getName() + ":" + element.getText());
break;
}
}
break;
}
}
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("修改成功");
}
}
集合
2.外部类外部:StaticInnerClass.Inner inne






import java.util.HashSet;
import java.util.Set;
public class Worker {
private String name;//姓名
private int age;//年龄
private int salary;//收入
public Worker(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.name.hashCode() + age + salary;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Worker obj2 = (Worker) obj;
if (this.name.equals(obj2.name) && this.age == obj2.age && this.salary == obj2.salary) {
return true;
}
return false;
}
public static void main(String[] args) {
Set<Worker> hashSet = new HashSet<>();
//hashcode作为索引或者说是唯一标识
hashSet.add(new Worker("zhang3", 18, 1500));
hashSet.add(new Worker("li4", 18, 1500));
hashSet.add(new Worker("wang5", 18, 1600));
hashSet.add(new Worker("zhao6", 18, 2000));
hashSet.add(new Worker("zhao6", 18, 2000));
for (Worker worker : hashSet) {
System.out.println(worker);
}
}
}
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Worker implements Comparable {
private String name;//姓名
private int age;//年龄
private int salary;//收入
public Worker(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
@Override
public int compareTo(Object o) {
if (this == o) {
return 0;
} else {
if (o instanceof Worker) {
Worker worker = (Worker) o;
if (this.age != worker.getAge()) {
return this.age - worker.getAge();
} else if (this.salary != worker.getSalary()) {
return this.salary-worker.getSalary();
} else {
return this.name.compareTo(worker.getName());
}
} else {
try {
throw new Exception("只能比较Worker对象");
} catch (Exception e) {
e.printStackTrace();
}
}
}
return 0;
}
public static void main(String[] args) {
TreeSet<Worker> set = new TreeSet<>();
set.add(new Worker("zhang3", 18, 1500));
set.add(new Worker("li4", 18, 1500));
set.add(new Worker("wang5", 18, 1600));
set.add(new Worker("zhao6", 17, 2000));
for (Worker worker : set) {
System.out.print(worker.getName()+"\t");
}
}
}
System.out.println(str.charAt(2));//取字符 System.out.println(str.indexOf("l"));//取字符下标 System.out.println(str.concat(str1));//拼接 System.out.println(str.substring(3, 5));//(] } }
import java.util.Scanner;
public class Item05 {
public static void main(String[] args) {
char c;
String str;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
str=scanner.next();
System.out.println("请输入要查找的字符");
c=scanner.next().charAt(0);
if (str.indexOf(c)>-1){
int count=0;
for (int i = 0; i < str.length(); i++) {
if (c==(str.charAt(i))){
count++;
}
}
System.out.println(str+"中包含"+count+"个"+c);
}else {
System.out.println(str+"中不存在"+c);
}
}
}
public class Item06 {
public static void main(String[] args) {
String s = new String();
StringBuffer stringBuffer = new StringBuffer("1234556");
//千位分隔符
for (int i = stringBuffer.length() - 3; i > 0; i -= 3) {
stringBuffer.insert(i, ",");
}
System.out.println(stringBuffer);
}
}
I/O流


操作文件
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) {
File dir=new File("/tmp/Temp/temp");
File file = new File(dir,"text.txt");
if (!dir.exists()){
dir.mkdir();//创建目录
}
if (!file.exists()){//判断文件是否存在
try {
file.createNewFile();//创建文件
} catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println(file.getPath());
System.out.println(file.getName());
file.delete();//删除文件
dir.delete();//删除目录
}
System.out.println(file.exists());
}
}
使用FileInputStream读取文件
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
File dir = new File("/tmp/Temp/temp");
File file = new File("/tmp/Temp/temp/test.txt");
if (!dir.exists()) {
dir.mkdir();//新建目录
}
if (!file.exists()) {
try {
file.createNewFile();//新建文件
} catch (IOException e) {
e.printStackTrace();
}
}
//读取文件
try {
FileInputStream fileInputStream = new FileInputStream(file);
int num = fileInputStream.read();//一次读取一个字节
System.out.println(num);
int contentLength;
byte[] bytes= new byte[1024];
String content=null;
//超过1kb
while ((contentLength = fileInputStream.read(bytes))!=-1){
content=new String(bytes,0,contentLength);//转化成字符串
}
System.out.println(content);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用FileOutputStream写文件
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileWriteDemo {
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/good.txt");
String msg="weekend";
byte[] bytes=msg.getBytes(StandardCharsets.UTF_8);
fileOutputStream.write(bytes,0,bytes.length);//写文件
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedReader和FileReader读取文件
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferReaderDemo {
public static void main(String[] args) {
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader("/tmp/Temp/temp/test.txt"));
// int read = bufferedReader.read();//再次读取有可能丢失首字母
// System.out.println(read);
//按行读取
// String readLine = null;
// while ((readLine = bufferedReader.readLine()) != null) {
// System.out.println(readLine);
// }
//读取十个字符
// char[] chars = new char[10];
// int length = bufferedReader.read(chars, 0, chars.length);
// System.out.println(length);
// System.out.println(new String(chars,0,length));
//超过十个字符
// char[] chars = new char[10];
// int length=0;
// while ((length=bufferedReader.read(chars,0,chars.length))!=-1){
// System.out.println(new String(chars,0,length));
// }
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用BufferedWriter和FileWriter写文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferWriterDemo {
public static void main(String[] args) {
try {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("/tmp/Temp/temp/new.txt"));
bufferedWriter.write("first line");
bufferedWriter.newLine();//换行
bufferedWriter.write("second line");
bufferedWriter.newLine();
bufferedWriter.flush();//清楚空余
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化与反序列化
import java.io.*;
public class ObjectDemo {
public static void main(String[] args) {
// Student student = new Student("jack",20);
try {
//对象的序列化
// FileOutputStream fileOutputStream = new FileOutputStream("/tmp/Temp/temp/student.bin");
// ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//
// objectOutputStream.writeObject(student);
// objectOutputStream.close();
// fileOutputStream.close();
//反序列化
FileInputStream fileInputStream = new FileInputStream("/tmp/Temp/temp/student.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Student student = (Student) objectInputStream.readObject();
System.out.println(student);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
泛型
public interface Person<T> {
T getName();
void setName(T t);
}
public class Student<T> implements Person{
private T t;
public Student() {
}
public Student(T t) {
this.setName(t);
}
public void show(T t){
System.out.println(t.getClass().getName());
System.out.println(t);
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
@Override
public T getName() {
return this.t;
}
@Override
public void setName(Object o) {
this.t= (T) o;
}
public static void main(String[] args) {
// Student<String> student=new Student<>();
// student.show("jack");
Student<String> student = new Student<>("张三");
System.out.println(student.getName());
System.out.println(student.getT().getClass().getName());
}
}
多线程
进程:系统运行的基本单位,有独立的内存空间和系统资源
线程:进程中执行运算的最小单位,处理机分配给线程,即真正在处理机上运行的是线程
线程的创建的两种方式
继承java.lang.thread类
实现java.lang.Runnable接口(还是要借助于thread启动)
1.定义线程
2.创建线程对象
3.启动线程
4.终止线程(不推荐手动终止)
cpu会随机执行里面的线程:主线程,自定义线程
线程的声明周期包括四个状态:新生状态,可运行状态,阻塞状态和死亡状态
多个线程处于可运行的状态(线程调度)
分配优先级 1的优先级最高,默认值是5,Thread.currentThread().getPriority()
更改优先级 new Thread().setPriority(4)
new Thread().join()添加进阻塞进程
Thread.sleep(500)当前线程停止执行,进入不可运行状态(阻塞),其他等待运行的进程机会是相等的
yield当前线程转入暂停运行的状态(不阻塞),如果没有其他等待执行的线程,当前线程会马上恢复执行,会优先级相同的或更高的执行
线程同步
关键字synchronized
同步方法
同步代码块
线程通信
wait()挂起当前线程,并释放共享资源的锁
notify()在因调用该对象的wait方法二阻塞的线程中随机选择一个解除阻塞,但要等到获得锁后才可以正真执行
notifyall将因调用该对象的wait方法而阻塞的所有线程一次性全部解除阻塞
这三个方法只能在同步方法或者同步代码块中使用
线程创建
//1.定义线程:通过继承的方式
public class MyThread extends Thread{
//重写run
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
public static void main(String[] args) {
//cpu会随机执行里面的线程:主线程,自定义线程
//2.创建线程对象
MyThread myThread = new MyThread();
//3.启动线程
myThread.setName("我的线程");//定义线程名
myThread.start();
//主线程
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
// MyRun myRun = new MyRun();
// new Thread(myRun,"自定义线程名").start();//Thread才是真正的线程
//
// //主线程
// for (int i = 0; i < 5; i++) {
// //当前运行的是哪个线程
// System.out.println(Thread.currentThread().getName()+":"+i);
// }
//优先级只是cpu执行该线程的一个重要参考要素之一
MyRun myRun = new MyRun();
Thread t1 = new Thread(myRun, "线程1");
Thread t2 = new Thread(myRun, "线程2");
t1.setPriority(4);
t2.setPriority(6);
t1.start();
// t2.start();
for (int i = 0; i < 5; i++) {
//当前运行的是哪个线程
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(500);
}
}
}
分苹果
public class ShareApple implements Runnable {
private int count = 5;//苹果的总数
private boolean flag = true;//标记位,是否可以拿苹果
//拿苹果的方法
//同步方法
public synchronized boolean getApple() {
// synchronized (this) {//同步代码块
if (count == 0)//是否有苹果
return false;
count--;
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count >= 0) {
System.out.println(Thread.currentThread().getName() + "成功拿到了一个苹果,还剩" + count + "个苹果");
} else {
System.out.println(Thread.currentThread().getName() + "没有拿到苹果");
}
return true;
// }
}
@Override
public void run() {
while (flag)
flag = getApple();
if (count == 0) {
System.out.println(Thread.currentThread().getName() + "线程结束");
}
}
}
public class TestApple {
public static void main(String[] args) {
ShareApple shareApple = new ShareApple();
new Thread(shareApple,"小明").start();
new Thread(shareApple,"小黑").start();
}
}
存取款
public class Account {
private int balance = 500;
public int getBalance() {
return balance;
}
public void qu(int atm) {
balance -= atm;
}
}
public class TestAccount implements Runnable {
private Account account = new Account();
@Override
public void run() {
for (int i = 0; i < 4; i++) {
makeWithDraw(100);
if (account.getBalance() < 0)
System.out.println("账户透支");
}
}
private void makeWithDraw(int atm) {
synchronized (account) {
if (account.getBalance() >= atm) {
System.out.println(Thread.currentThread().getName() + "\t准备取款!");
account.qu(atm);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"\t完成取款");
}else {
System.out.println("余额不足以支付\t"+Thread.currentThread().getName()+"\t取款的余额为"+account.getBalance());
}
}
}
public static void main(String[] args) {
TestAccount testAccount = new TestAccount();
Thread p1 = new Thread(testAccount, "张三");
Thread p2 = new Thread(testAccount, "张三的妻子");
p1.start();
p2.start();
}
}
生产者消费者模式
public class Consumer extends Thread {//消费者
private ShareData data;
Consumer(ShareData data) {
this.data = data;
}
@Override
public void run() {
char s;
do {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
s = data.getChar();
} while (s != 'D');
}
}
public class Producer extends Thread {
private ShareData data;
Producer(ShareData data) {
this.data = data;
}
@Override
public void run() {
//专门生产
for (char i = 'A'; i <= 'D'; i++) {
data.produce(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ShareData {
private char c;
private boolean flag = false;//信号量
//生产资源
public synchronized void produce(char c) {
while (flag) {
try {
System.out.println("生产资源:消费者还没有消费,需要等待消费者进行消费");
wait();//线程立即挂起,释放锁和cpu资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = true;
notify();
this.c = c;
System.out.println("生产资源:生产者已经生产了产品" + c + ",等待消费者消费");
}
//消费资源
public synchronized char getChar() {
while (!flag) {
try {
System.out.println("消费资源:生产者还没有生产,无法消费消费。。。");
wait();//线程立即挂起,释放锁和cpu资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = false;
notify();
System.out.println("消费资源:消费者消费了产品" + c + "通知生产者生产");
return c;
}
}
public class TestConsumer {
public static void main(String[] args) {
ShareData data = new ShareData();
new Producer(data).start();
new Consumer(data).start();
//定义了两个线程:每一次 都来争夺cpu资源
}
}
死锁
public class DeadLockRunnable implements Runnable {
//编号
public int num;
//资源
private static Object chopsticks1 = new Object();
private static Object chopsticks2 = new Object();
private boolean flag =false;//信号量
/**
* num = 1 拿到chopsticks1 等待chopsticks2
* num = 2 拿到chopsticks2 等待chopsticks1
*/
@Override
public void run() {
if (num==1){
System.out.println(Thread.currentThread().getName()+"拿到了chopsticks1,等待chopsticks2");
synchronized (chopsticks1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (chopsticks2){
System.out.println(Thread.currentThread().getName()+"用餐完毕");
}
}
}
else if (num==2){
System.out.println(Thread.currentThread().getName()+"拿到了chopsticks2,等待chopsticks1");
synchronized (chopsticks2){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (chopsticks1){
System.out.println(Thread.currentThread().getName()+"用餐完毕");
}
}
}
}
}
public class DeadLockTest {
public static void main(String[] args) {
DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
deadLockRunnable1.num=1;
DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
deadLockRunnable2.num=2;
new Thread(deadLockRunnable1,"张三").start();
new Thread(deadLockRunnable2,"李四").start();
}
}
线程通信
客户端与服务端
InetAddress类 无构造方法 getLocalHost获取本地ip getByName获取网络主机名
基于tcp:Socket(客户端)和Server Socket(服务器端)
ServerSocket.accept():获取客户端socket
Socket通信模型
进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
两个Socket类的构造方法及其含义
Socket socket=new Socker("localhost",8800)
ServerSocket serverSocket = new ServerSocket(9000);
socket.getOutputStream();
os.write
1.建立连接
2.打开Socket关联的输入输出流
3.数据流中读写信息
4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {//客户端
//创建Socket
Socket socket = new Socket(InetAddress.getLocalHost(),9000);
//得到输出流
OutputStream os = socket.getOutputStream();
//写入字符串
// String msg="你好,服务器端,这是用户登录信息";
// os.write(msg.getBytes(StandardCharsets.UTF_8));
//写入对象
ObjectOutputStream objectOutputStream = new ObjectOutputStream(os);
User user = new User("Jack","123");
objectOutputStream.writeObject(user);
//告诉服务器,消息发完了
socket.shutdownOutput();
//得到输入流
InputStream is = socket.getInputStream();
//读取信息
byte[] by = new byte[1024];
int len ;//= is.read(by);
String content=null;
//超过1kb
while ((len=is.read(by))!=-1){
content=new String(by,0,len);
}
System.out.println("客户端发送的信息是:"+content);
//告诉服务器,消息发完了
// socket.shutdownOutput();
//关闭
is.close();
os.close();
socket.close();
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class MyServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建的是ServerSocket,指定对应的端口号
System.out.println("服务器请求链接");
ServerSocket serverSocket = new ServerSocket(9000);
//2.等待链接
Socket socket = serverSocket.accept();
System.out.println("服务器等待链接");
//3.得到输入流,其实就是客户端的输出流
InputStream is = socket.getInputStream();
//4.1读取字符串信息
// byte[] by = new byte[1024];
// int len;//= is.read(by);
// String content = null;
// //超过1kb
// while ((len = is.read(by)) != -1) {
// content = new String(by, 0, len);
// }
// System.out.println("客户端发送的信息是:" + content);
//4.2读取对象
ObjectInputStream ois = new ObjectInputStream(is);
User user = (User) ois.readObject();
String msg2=null;
if ("123".equals(user.getPassword())){
msg2="欢迎你"+user.getUsername();
}else {
msg2="用户名或密码错误";
}
System.out.println(msg2);
//得到输出流,对客户端进行响应
OutputStream os = socket.getOutputStream();
String msg = "你好,客户端,信息已经收到";
//writer
os.write(msg.getBytes(StandardCharsets.UTF_8));
//5.关闭资源
is.close();
os.close();
socket.close();
serverSocket.close();
}
}
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
服务器端与多客户端
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class LoginServer {//多线程处理客户端
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9000);
Socket socket;
System.out.println("服务器等待请求。。。。");
while (true) {//实现一直监听
socket = serverSocket.accept();
System.out.println("服务器接收到请求");
//多线程
LoginThread thread = new LoginThread(socket);
thread.start();
}
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class LoginClient1 {
public static void main(String[] args) throws IOException {
User user = new User("张三", "123");
Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("我是客户端1,给服务器发送登录信息。。。");
oos.writeObject(user);
//告诉服务已经发送完了消息
socket.shutdownOutput();
//接收服务器的信息
byte[] temp = new byte[1024];
int len = is.read(temp);
System.out.println("服务器的响应"+new String(temp,0,len));
socket.close();
}
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class LoginClient2 {
public static void main(String[] args) throws IOException {
User user = new User("李四", "123");
Socket socket = new Socket(InetAddress.getLocalHost(), 9000);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("我是客户端2,给服务器发送信息");
oos.writeObject(user);
//告诉服务已经发送完了消息
socket.shutdownOutput();
//接收服务器的信息
byte[] temp = new byte[1024];
int len = is.read(temp);
System.out.println("服务器的响应"+new String(temp,0,len));
socket.close();
}
}
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class LoginThread extends Thread {
private Socket socket;
public LoginThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//处理客户端请求
try (//写在小括号里会自动关闭资源close
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ObjectInputStream ois = new ObjectInputStream(is);
) {
//得到客户端的信息
User user = (User) ois.readObject();
//给客户端回信息
String msg = null;
if (user == null) {
msg = "没有发送登录信息,登录失败";
} else {
msg = "欢迎你" + user.getUsername();
}
System.out.println(msg);
os.write(msg.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
网络编程
ip地址与主机名
C类地址(192.0.0.0-223.255.255.0):192.168.0.0~192.168.255.255
InetAddress类 无构造方法 getLocalHost获取本地ip getByName获取网络主机名
基于tcp:Socket(客户端)和Server Socket(服务器端)
ServerSocket.accept():获取客户端socket
Socket通信模型
进行网络通信是,Socket需要借助数据流来完成数据的传递工作
Socket类
两个Socket类的构造方法及其含义
Socket socket=new Socker("localhost",8800)
ServerSocket serverSocket = new ServerSocket(9000);
socket.getOutputStream();
os.write
1.建立连接
2.打开Socket关联的输入输出流
3.数据流中读写信息
4.关闭所有的数据流和Socket
ServerSocket类的accept()方法有何用处:获取客户端socket
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestAddress {
public static void main(String[] args) throws UnknownHostException {
//InetAddress:IP地址包装类
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.getHostAddress());//ip地址
System.out.println(localHost.getHostName());//主机名
//得到网络主机名
InetAddress address = InetAddress.getByName("www.baidu.com");
System.out.println(address.getHostAddress());
System.out.println(address.getHostName());
}
}
UDP
基于UDP协议的Socket编程
1.利用DatagramSocket发送数据包
2.利用DatagramPacket对象封装数据包
3.利用DataGramPacket处理数据包
4.利用DataGramPacket接收数据包
建立发送端,接收端
创建数据
建立数据包
调用Socket的发送接收方法
关闭SOcket
发送端与接收端是两个独立运行的程序
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
public class UDPSend {//发送端
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
byte[] msg = "最新的邮件来了。。。。".getBytes(StandardCharsets.UTF_8);
//创建数据包,即将发送出去的数据包,发送的内容,收获的ip,端口号,
DatagramPacket dp = new DatagramPacket(msg, 0, msg.length, InetAddress.getByName("localhost"), 9000);
//发送数据
ds.send(dp);
//关闭资源:socket
ds.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UDPReceive {
public static void main(String[] args) throws IOException {//接收端
//1.创建DatagramSocket
DatagramSocket ds = new DatagramSocket(9000);
//2.创建Packet
byte[] temp = new byte[1024];
DatagramPacket dp = new DatagramPacket(temp, temp.length);
//3.接收数据
ds.receive(dp);
//发送方的主机名
String hostName = dp.getAddress().getHostName();
//发送方的端口号
int port = dp.getPort();
System.out.println("发送方的主机名是"+hostName+"发送方的端口号是"+port);
byte[] bytes = dp.getData();//获取接收到的内容
String msg=new String(bytes,0, dp.getLength());
System.out.println("发送过来的信息是:"+msg);
//4.关闭资源
ds.close();
}
}
DOM文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student id="1">
<name>王同</name>
<class>java</class>
<score>89</score>
</student>
<student id="2">
<name>李佳</name>
<class>sql</class>
<score>58</score>
</student>
<student id="3">
<name>李白</name>
<class>python</class>
<score>90</score>
</student>
</students>
<!ELEMENT students (student+)> <!ELEMENT student (name,class,score)> <!ATTLIST student id CDATA #IMPLIED> <!ELEMENT name (#PCDATA)> <!ELEMENT class (#PCDATA)> <!ELEMENT score (#PCDATA)>
public class TestXML {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
//1.得到document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//2.解析和加载xml文件到内存中去
Document document = documentBuilder.parse("student.xml");
//3.返回文档中的所有子节点
NodeList nodeList = document.getChildNodes();
Node root = nodeList.item(nodeList.getLength() - 1);
System.out.println("root:" + root.getNodeName());//students
//4.再查找他的子节点
NodeList childNodes = root.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if ("student".equals(item.getNodeName())) {
NodeList nodes = item.getChildNodes();
for (int j = 0; j < nodes.getLength(); j++) {
Node node = nodes.item(j);
if ("name".equals(node.getNodeName())) {
System.out.println("name:" + node.getTextContent());
} else if ("class".equals(node.getNodeName())) {
System.out.println("class:" + node.getTextContent());
} else if ("score".equals(node.getNodeName())) {
System.out.println("score:" + node.getTextContent());
}
}
}
}
}
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
import java.io.IOException;
public class UpdateXML {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException {
//使用DOM对XML文件进行数据修改
//1.得到document
DocumentBuilderFactory dbf;
dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
//解析和加载xml文件到内存中去
Document document = documentBuilder.parse("student.xml");
//1.删除某个节点
// NodeList list = document.getElementsByTagName("student");
// for (int i = 0; i < list.getLength(); i++) {
// Element item = (Element)list.item(i);
// //node:节点(文本节点),element:元素
// //凡是元素都是节点,但是节点不一定都是元素,例如:一个单纯的回车也是节点
//// System.out.println(item.getAttribute("id"));
// if ("2".equals(item.getAttribute("id"))){
// item.getParentNode().removeChild(item);
// }
// }
//2.添加节点
// //student(name class score)
// Element student = document.createElement("student");
// student.setAttribute("id", "3");//设置属性值
// //name
// Element stuName = document.createElement("name");//创建节点
// stuName.setTextContent("李白");//设置节点内容
// student.appendChild(stuName);//添加节点
// //class
// Element stuClass = document.createElement("class");
// stuClass.setTextContent("python");
// student.appendChild(stuClass);
// //score
// Element stuScore = document.createElement("score");
// stuScore.setTextContent("90");
// student.appendChild(stuScore);
// //找到根节点students
// NodeList nodeList = document.getElementsByTagName("students");
// Node students = nodeList.item(nodeList.getLength() - 1);
// students.appendChild(student);
//修改:李白-》李清照
//1.查找节点
NodeList student3 = document.getElementsByTagName("student");
for (int i = 0; i < student3.getLength(); i++) {
Element item = (Element)student3.item(i);
if ("3".equals(item.getAttribute("id"))){
Node name = item.getElementsByTagName("name").item(0);
//2.修改节点内容
name.setTextContent("李清照");
break;
}
}
//保存成XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
// 设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
StreamResult result = new StreamResult(new FileOutputStream("student.xml"));
// 把DOM树转换为XML文件
transformer.transform(domSource, result);
}
}
DOM4j
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="book1">
<name>三国演义</name>
<price>99.88</price>
</book>
<book id="book2">
<name>西游记</name>
<price>77.88</price>
</book>
<book id="book3">
<name>李白的诗</name>
<price>88.88</price>
</book>
</books>
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.Iterator;
import java.util.List;
public class TestDom01 {
public static void main(String[] args) throws DocumentException {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
System.out.println(root.getName());//root
//遍历显示所有的数据
List<Element> list = root.elements("book");
for (Element book:list){
Attribute id = book.attribute("id");
System.out.println("id:"+id.getValue());
//迭代器
Iterator<Element> it = book.elementIterator();
while (it.hasNext()){
Element element = it.next();
System.out.println(element.getName()+":"+element.getText());
}
System.out.println("----------------");
}
}
}
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class TestDom02 {
public static void main(String[] args) throws DocumentException, IOException {
//需求:实现 删除 id="book3"这样的一个节点
/*
<book id="book">
<name>李白的诗</name>
<price>88.88</price>
</book>
*/
//解析xml文件
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
//找到相应的节点
List<Element> bookList = root.elements("book");
for (Element book:bookList){
Attribute id = book.attribute("id");
if ("book3".equals(id.getValue())){
book.getParent().remove(book);//删除
}
}
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("删除成功");
}
}
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class TestDom03 {
public static void main(String[] args) throws DocumentException, IOException {
//需求:实现 新增节点
/*
<book id="book">
<name>李白的诗</name>
<price>88.88</price>
</book>
*/
//解析xml文件
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
//新增节点
Element book = DocumentHelper.createElement("book");
book.addAttribute("id", "book3");
Element name = DocumentHelper.createElement("name");//创建节点
name.setText("李白的诗");//设置属性
book.add(name);//添加节点
Element price = DocumentHelper.createElement("price");
price.setText("88.88");
book.add(price);
root.add(book);
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("新增成功");
}
}
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
public class TestDom04 {
public static void main(String[] args) throws DocumentException, IOException {
//需求 实现 修改 id="book3"这样的一个节点 李白的诗-》李清照的诗句2.外部类外部:StaticInnerClass.Inner inne
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("books.xml");
//得到根节点
Element root = doc.getRootElement();
System.out.println(root.getName());//root
//遍历所有的数据
List<Element> list = root.elements("book");
for (Element book : list) {
//找到对应的节点
if ("book3".equals(book.attribute("id").getValue())) {
//迭代器
Iterator<Element> it = book.elementIterator();
while (it.hasNext()) {
Element element = it.next();
//找到要修改的文本
if ("李白的诗".equals(element.getText())) {
element.setText("李清照的诗");
System.out.println(element.getName() + ":" + element.getText());
break;
}
}
break;
}
}
//保存到xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter("books.xml"));
writer.write(doc);
writer.close();
System.out.println("修改成功");
}
}
集合
2.外部类外部:StaticInnerClass.Inner inne






import java.util.HashSet;
import java.util.Set;
public class Worker {
private String name;//姓名
private int age;//年龄
private int salary;//收入
public Worker(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.name.hashCode() + age + salary;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Worker obj2 = (Worker) obj;
if (this.name.equals(obj2.name) && this.age == obj2.age && this.salary == obj2.salary) {
return true;
}
return false;
}
public static void main(String[] args) {
Set<Worker> hashSet = new HashSet<>();
//hashcode作为索引或者说是唯一标识
hashSet.add(new Worker("zhang3", 18, 1500));
hashSet.add(new Worker("li4", 18, 1500));
hashSet.add(new Worker("wang5", 18, 1600));
hashSet.add(new Worker("zhao6", 18, 2000));
hashSet.add(new Worker("zhao6", 18, 2000));
for (Worker worker : hashSet) {
System.out.println(worker);
}
}
}
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Worker implements Comparable {
private String name;//姓名
private int age;//年龄
private int salary;//收入
public Worker(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Worker{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
@Override
public int compareTo(Object o) {
if (this == o) {
return 0;
} else {
if (o instanceof Worker) {
Worker worker = (Worker) o;
if (this.age != worker.getAge()) {
return this.age - worker.getAge();
} else if (this.salary != worker.getSalary()) {
return this.salary-worker.getSalary();
} else {
return this.name.compareTo(worker.getName());
}
} else {
try {
throw new Exception("只能比较Worker对象");
} catch (Exception e) {
e.printStackTrace();
}
}
}
return 0;
}
public static void main(String[] args) {
TreeSet<Worker> set = new TreeSet<>();
set.add(new Worker("zhang3", 18, 1500));
set.add(new Worker("li4", 18, 1500));
set.add(new Worker("wang5", 18, 1600));
set.add(new Worker("zhao6", 17, 2000));
for (Worker worker : set) {
System.out.print(worker.getName()+"\t");
}
}
}

浙公网安备 33010602011771号