1.java基础详解

1.2021/4/2
1.基本类型的字面值(5条)
2. 整数字面值是int类型
int x = 99999;//对,右面数据的字面值是int类型
int x = 99999999999;//错,右面数据的字面值是int类型,但是已经超出int的取值范围。

  1. byte,short,char三种类型可以在其范围内可以直接赋值
    byte b1=127;//对,
    byte b2=128;//错,超出byte范围

4.浮点数的字面值是double类型

double r =3.14;//对
float r =3.14;//错,右面的数据字面值是double,float是4字节存不下double类型的数据

5.字面值后缀L D F

	long x =99999999999L;//字面值是int类型,需转成long类型的数据,加字面值后缀L即可
	float b = 3.0F;//3.0字面值是double类型,加后缀F会变成float类型
	double d = 3D;//3字面值是int类型,加后缀D,会变成double类型
  1. 进制前缀
    0b - 标识这是2进制 ,如:0b0101
    0 - 标识这是8进制, 8进制是三位,如: 023
    0x - 标识这是16进制,如: 0x0001
    \u -标识这是char类型,属于16进制

7.类型转化:小到大,直接转 大到小,强制转 浮变整,小数没;
Infinity 无穷大 3.14/0
NaN not a number 0/0.0 或 0.0/0

8.向上驼峰命名,首字母大写(对类进行命名)

9.向下驼峰命名,除首字母为其他单词首字母大写(方法进行命名)

10.Ctrl+F可以对代码进行替换

11.int e = 1; System.out.println(–e-e-e–);//打印结果0

12.方法的重载:
1.在一个Java类中,定义多个同名的方法,如果方法名相同,参数个数不同、参数类型不同、顺序不同即为重载

13.数组定义方式
1.int[] arr3=new int[]{1,2,3,4,5,6,7,22}; 2.int[] a = new int[5] 3.int[] a = {}
14.javaEE,javaSE,javaME
1.javaME就是用来开发嵌入式的,javaSE就是java基础,javaEE就是用来开发企业端的,采用SSH框架和SSM框架使用的是javaEE的技术。
2.Java SE指的是Java Standard Edition,Java标准版,主要用于桌面应用开发,同时也是Java的基础,javase包含Java语言基础、JDBC (Java数据库连接性)操作、I/O(输出输出)操作、网络通信、多线程等技术。

		  3.JavaEE指的是Java Enterprise Edition,Java企业版,多用于企业级开发,包括web开发等方面,Java EE是在JavaSE的基础上构建的他提供Web 服务、组建模型、管理和通信API

总之,在学校期间一般学的是JavaSE,在企业用的则是JavaEE,javaEE基于javaSE之上

2021/4/6
1.for循环的执行顺序(2021/4/6)4
for(初始条件(1);循环条件(2);结束条件(3)){
代码块4
}
1–2—4–3—2---4—3直到循环条件不满足为止,其中初始条件执行1次
3.2021/4/7
1.随机数对象,switch的注意事项
1.创建一个工具类对象new Random()调用nextInt(10)方法 产生一个10以内的随机数
2. Switch的注意事项
判断条件,只支持int byte short char String类型的数据
当成功匹配到了case之后,要向后穿透所有的case
default是无论什么时候都会执行(如果没遇到break的话);
3.创建测试方法
单元测试方法junit:测试某些功能
语法要求:方法的标记 @Test + void + public + 无参
测试:选中方法名-右键-run as-junit test…
创建方法时需要导入import org.junit.jupiter.api工具的.Test;类
4.2021/4/8
1. break与continue之后不能再出现其他语句,且只能在循环中使用
2.成员变量的默认值:byte short int long 默认值为0,float double默认值为0.0,char默认值为’\u0000’;
1. char[] a = {‘h’,‘e’,‘l’,‘l’,‘0’};System.out.println(a);
直接对元素的值进行输出,底层以遍历
2.引用类型的默认值为null
3.面向对象和面向过程,面向对象直接得到结果,面向过程注重细节。
4.一个类中定义一个类属它们之间并列,public只能修饰与.java文件相同的类,并列的类无法用访问修饰符修饰。
5.Arrays.toString(a)Arrays工具类,将数组a转化为字符串
6.Arrays.sort(a);对数组进行排序
7.Arrays.copyOf(a, 10);复制数组//新数组的长度
5.2021/4/9
1.封装的理解
1.通过private修饰符对属性及方法进行封装,将属性和方法封装到类中,只能在类中使用,
其他类访问只能访问它的公共的方法以间接访问封装的属性,封装提高安全性
示例1:
(1)package com.tedu.basic;
/**功能测试封装

  • 与Student类文件共用

  • */
    public class TesteEncapsolotion {
    public static void main(String[] args) {
    Student student1 = new Student();
    //未将Student封住时调用
    //student1.name = “李兴军”;neme被封装无法使用

     	student1.setName("李兴军");
     	System.out.println(student1.getName());
     }
    

}
(2)
package com.tedu.basic;

public class Student {

	private String name;
	int no;
	char sex;
	//1.给外界提供获取方式 
	public String getName() {return name;}
	
	//2.给外键提供设置方式
	public void setName(String name) {this.name = name;}
	
	//爱好
	private static void hoppy() {System.out.println("我爱java");}
	//打游戏
	public static void playcomputer() {System.out.println("我爱王者");}

}
2.new Person();//匿名对象
3.
创建构造代码块,new实例时执行,先执行代码块,在执行构造方法,提高了代码的复用性,在类里,方法外创建。
局部代码块:方法调用时触发,控制变量的使用范围,可以多成嵌套
创建格式为:
{

}

3.this关键字的使用规则
1.类内部资源的相互调用,this关键字调用的资源,调用本类的资源.
2.成员变量和局部变量重名在局部的方法之中通过this关键字调用,则引用的是成员变量
3.可以在构造方法中调用其他构造方法,构造方法调用其他构造方法时,必须在第一行使用
否则报错,构造方法通过this调用其他构造方法,构造方法间通过this关键字调用时,不能构成循环,否则报错(this(参数列表)的方式完成构造方法之间的调用)
4.this关键字底层创建了一个这个类的实例,然后可以对类中的资源进行调用

5.通过extends关键字实现继承
1.子类继承父类,可以创建子类实例使用父类的功能,可以在父类的基础上扩充新的功能
2.子类不能使用父类中创建的私有属性和私有方法(父类的秘密)
3.继承具有传递性
6.2021/4/10
1.JVM的跨平台原理
我们所写的JAVA程序是".java"为后缀的源文件,这些文件需要进行编译环节,变为以".class"为后缀的字节码文件,交由JVM(JAVA虚拟机)来运行.不同的OS(操作系统)都有与之对应的JVM,所以只需要写一个Java程序,就可以在多个不同的操作系统上执行。这样就实现了Java程序的跨平台性。也称为Java具有良好的可移植性。
2.驼峰命名规则
1.小驼峰命名法:除第一个字母外其余字母首字母大写,用于方法名和变量名之中
大驼峰命名法:所有单词首字母大写,用于类名
7.2021/4/12
1.Super关键字的使用
1.super.name子类中调用父类的成员变量
2.super.eat()子类中重写父类的方法后,调用被覆盖的父类方法
3.子类继承父类之后,默认的构造方法里有默认的super()(调用父类构造且只能在第一行),如果父类没有无参构造,则子类只能调用有参构造
2.Static关键字的使用
1.Static可以修饰成员变量和成员方法
2.Static资源优先于对象的加载
3.Static资源是共享的,可以直接被类名调用
4.静态变量是共享
5.Static静态资源只能访问静态资源不能非静态资源(本类之中,创建本类实例对象可直接访问静态成员(静态方法和静态变量))
6.静态代码块(类里方法外),类加载时触发,静态代码块最先执行,在执行构造代码块,执行构造方法,在通过实例执行局部代码块
7.静态代码块中只加载一次
3.final关键字
1.Final修饰的类不能被继承
2.Final修饰的变量,不能被修改
3.Final修饰的方法,不能被重写
注意:this代表本类的对象的引用,Super:代表父类的对象的引用,重写的要求:子类的与父类的参数列表相同和访问修饰的权限小于等于父类

  1. 2021/4/13
    1.多态的理解
    1. 多态对象子类的类型是父类,口诀1:以父类方法为标准(有则行,无则错),口诀2:编译看左边,运行看右边(运行的是子类重写的方法)

    2. 子类想使用自身的功能,则创建子例实例调用

    3. private ,构造方法 不能被继承

    4. static ,final, private ,构造方法不能被重写

    5. 多态的特性增强程序的通用性 / 统一标准

    6. 多态:多态根本不关心具体的子类类型,屏蔽掉了子类之间的不同,把子类当父类来看
      2.异常

      1. 捕捉异常,可能出错的语句块写在try语句快中,遇到错误时匹配相应的cath块进行处理,报错后,后面不在执行的语句,catch语句块中通过e.printStackTrace()方法跟踪错误
        finall语句块可执行遇到错误后不再执行的语句,任何时候都会执行
        2.抛出异常throws exception 方法抛出异常,方法体中出现错误直接抛出异常给调用者
        3.抽象类及抽象方法
        1.抽象类里可以包含抽象方法和普通方法
        2.如果一个类里包含着抽象方法,那么,这个类必须设计成抽象类
        3.抽象类和抽象方法被abstract修饰
        4.父类是抽象类子类重写父类所有抽象方法
        5.抽象类和普通类之间多了个抽象方法
        9.2021/4/14
        1.接口,多继承和多实现以及对父类方法的重写
        1.接口和抽象类都无法实例化
        2.实现类实现接口(或继承抽象类),实现类要么改为抽象类,要么重写抽象方法
        3.接口没有构造方法
        4.接口中的变量默认常量
        5.接口中可简写抽象方法
        6.JDK1.8之前接口中不能创建普通方法
        7.接口中能实现多继承,接口之间的继承不重写抽象方法
        8.类可以实现多个接口,重写所有抽象方法
        9.实现类可以在继承的同时,多实现。继承所有的抽象方法
        10.所有类都是object的子类
        11.子类中如果不想使用父类object中的方法,则子类可重写父类中的方法,在通过子类实例调用
        12.Java找错,首先看异常,是什么异常,寻找自己的类,找自己类中的方法能够准确定位错误
    7. 类实现接口,实现类中的构造方法中的super调用的是Object对象
      14.多态对象想使用子类的功能可以向下造型
      10.2021/4/15
      1.String的理解
      1.String s = “s”;是一个常量,存在常量池中,底层创建了一个对象。,字符串底层是个字符数组,相比new String对象而言更加高效,底层是一个不可变的数组
      2.Stirng的方法集,s2是一个字符串对象
      char a = s2.charAt(0);//根据下标0获取对应的字符h
      System.out.println(a);

      	String b = s2.concat("123");//拼接字符串
      	System.out.println(b);//hello123
      	boolean c = s2.endsWith("lo");//判断s2是否以"lo"结尾
      	System.out.println(c);//true
      	//TODO 调用以下方法
      	System.out.println( s2.contains("o") );//判断s2是否包含"o"
      	System.out.println( s2.endsWith("o") );//判断s2是以"o"结尾
      	System.out.println( s2.equals("hello") );//String重写了equals()
      	System.out.println( s2.hashCode() );//获取s2在内存中的哈希码值
      	System.out.println( s2.indexOf("l") );//获取s2里"l"第一次出现的索引
      	System.out.println( s2.lastIndexOf("l") );//获取s2里"l"最后一次出现的索引
      	System.out.println( s2.isEmpty() );//判断s2是否为空
      	System.out.println( s2.length() );//获取s2的长度
      	System.out.println( s2.replace('l','a') );//把旧字符换成新字符
      	System.out.println( s2.startsWith("he") );//判断是否以"he"开始
      	System.out.println( s2.substring(2) );//从2索引开始截取子串
      	System.out.println( s2.substring(1,3) );//从1索引开始,到3结束截取子串[1,3)-含头不含尾
      	System.out.println( s2.toLowerCase() );//全转小写
      	System.out.println( s2.toUpperCase() );//全转大写
      	s2="  a v c ";
      	System.out.println( s2.trim() );//去掉多余空格
      	System.out.println( s2.matches("abc") );//判断是否匹配
      	String x = String.valueOf(100);//把其他类型转成String类型
      	System.out.println(x+1);//1001
      	byte[] bs = s2.getBytes();//把每个字符对应的数字,存入 byte[]
      	//[32, 32, 97, 32, 118, 32, 99, 32]
      	System.out.println(Arrays.toString(bs));
      	s2="ab1c1d1";
      	String[] ss = s2.split("1");//按照规则切割字符串
      	System.out.println(Arrays.toString(ss));//[ab, c, d]
      	char[] cs = s2.toCharArray();//把字符串里的每个字符存入char[]
      	System.out.println(Arrays.toString(cs));//[a, b, 1, c, 1, d, 1]
      	
      	//TODO String练习:获取指定字符串里的每个字符
      	String m="abcdefghijklmn";
      	//方式1:变成char[],再遍历char[]
      	char[] n = m.toCharArray();
      	for (int i = 0; i < n.length; i++) {
      		System.out.println(n[i]);
      	}
      	//方式2:变成byte[],再遍历byte[]
      	byte[] m2 = m.getBytes();
      	for (int i = 0; i < m2.length; i++) {
      		byte data  = m2[i];
      		char n2 = (char)data;//强转,把byte->char
      		System.out.println(n2);
      	}
      	//方式3:直接遍历字符串,获取里面的字符
      	for (int i = 0; i < m.length(); i++) {
      		char data = m.charAt(i);//根据下标i,获取字符
      		System.out.println(data);
      	}
      

2.StringBuilder/StringBufferd()底层是一个可变的字符数组
1.专门用来解决 字符串拼接的(使字符串拼接更高效)
2.创建对象StringBuilder() – 无参构造
3.StringBuilder append(String str) – 拼接方法(对字符串进行拼接)
4.StringBuilder的拼接速度大于StirngBuffer,两者拼接的速度大于+号的拼接速度
3.Date和SimpleDateFormat
1.类 Date 表示特定的瞬间,精确到毫秒。
2.创建对象Date() --无参构造
3.Date的常用方法
//1,创建对象 --Date()
Date d = new Date();//创建Date对象 //创建Date对象直接获取系统时间
//2,调用方法
System.out.println(d.getDate());//今天是几号
System.out.println(d.getDay());//今天礼拜几
System.out.println(d.getHours());//现在几时
System.out.println(d.getMinutes());//现在几分
System.out.println(d.getMonth()+1);//现在几月 0~11
System.out.println(d.getSeconds());//现在几秒
System.out.println(d.getTime());//自1970.1.1零点
System.out.println(d.getYear()+1900);//自1900年算
System.out.println(d.toLocaleString());//2021-4-15 14:50:35

public static void method2() throws Exception {
//1,输入的出生日期
String data = new Scanner(System.in).nextLine();
//2,开始算天数
//2.1,创建对象 – SimpleDateFormat(String pattern)
SimpleDateFormat sdf =
new SimpleDateFormat(“yyyy-MM-dd”);
//2.2,Date parse(String text)
Date birthday = sdf.parse(data);//String -> Date
//2.3,算
long start = birthday.getTime();//获取出生时的ms
long now = System.currentTimeMillis();//获取当前时间的ms
System.out.println( (now-start)/1000/60/60/24 );//ms->天
}
4. BigDecimal/BigInteger
1,概述
BigDecimal – 专门解决小数运算不精确的问题
BigInteger – 专门解决超大的整数运算
2,创建对象
BigDecimal(String val)
3,常用方法
加法:BigDecimal add(BigDecimal augend)
减法:BigDecimal subtract(BigDecimal subtrahend)
乘法:BigDecimal multiply(BigDecimal multiplicand)
除法:BigDecimal divide(BigDecimal divisor)
BigDecimal bd1 = new BigDecimal(String.valueOf(a));
BigDecimal bd2 = new BigDecimal(b+"");
创建BigDecimal对象,将构造方法中的参数,如果是double类型转化为字符串类型(方法如上)在进行运算操作
5. 包装类
1.概述
包装类 就是为 基本类型 提供丰富的方法
基本类型:byte short int long float double char boolean
包装类型:Byte Short Integer Long Float Double Character Boolean
Byte Short Integer Long Float Double父类是Number
2. Number:
用来把包装类型 变回成 基本类型的各种方法/intValue()/byteValue()…
3.Integer
1.创建对象:Integer(int value)
2.把基本类型 变成 包装类型
Integer i = new Integer(5);
Integer c = Integer.valueOf(5);
3.int a = i.intValue();//把包装类型 变成 基本类型
4.int b = Integer.parseInt(“5”);//把字符串 转成 基本类型

11.20214/4/16

  1. File工具类
    1.概述
    IO技术主要用来解决 Java程序和文件系统的交互
    I是指 java程序读取磁盘中的数据
    O是指 从Java程序中输出到磁盘 的过程-out
    两个过程都是相对Java程序而言
    由于你操作数据的单位不同txt/jpg/mp4…分为两种流:字节流/字符流
    字节流可以读写任何单位的数据 – 重点!!!
    字符流 只可以读写txt的数据 – 了解!!!
    2.创建对象
    File(String pathname) pathname可以指示文件目录,也可以指向文件
    创建对象–参数是文件所在的路径
    File file = new File(“E:\iotest\1.txt”);
    //2,调用方法
    System.out.println( file.length() );//获取字节量
    System.out.println( file.exists() );//判断文件是否存在
    System.out.println( file.isFile() );//判断是文件吗
    System.out.println( file.isDirectory() );//判断是文件夹吗
    System.out.println( file.getName() );//获取文件名
    System.out.println( file.getParent() );//获取父路径
    System.out.println( file.getAbsolutePath() );//获取完整路径
    \前提文件不存在才可创建
    System.out.println( file.createNewFile() );//创建新文件
    \创建单级文件夹且该文件夹不存在创建该文件夹
    System.out.println(file.mkdir());
    \创建多级目录且该多级目录不存在
    System.out.println(file.mkdirs());//创建新多级文件夹
    System.out.println(file.delete());//删除文件或者空的文件夹
    2.读取流
    1.概述
    用来读取 磁盘里的数据 -in
    字符流只能读字符文件–了解
    字节流可以读各种文件–重点
    InputStream - FileInputStream - BufferedInputStream
    2.工具类
    1.InputStream:是父类,被修饰为了抽象类。不能被new,学习共性方法。
    abstract int read() 从输入流中读取数据的下一个字节。
    2.int read(byte[] b)
    从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
    3.int read(byte[] b, int off, int len)
    将输入流中最多 len 个数据字节读入 byte 数组。
    4.void close()
    关闭此输入流并释放与该流关联的所有系统资源。
  2. FileInputStream:是子类,可以使用父类的方法,研究new
    FileInputStream(String name)
    FileInputStream(File file)
    6.BufferedInputStream:是子类,可以使用父类的方法,研究new
    BufferedInputStream(InputStream in)
    创建一个 BufferedInputStream对象
    3.通过输入流读取文件中的数据
    1.将数据读取到数据流中,在通过int read()方法读取到java程序中
    InputStream in = new BufferedInputStream(new FileInputStream(“E:\iotest\1.txt”));
    InputStream in = new FileInputStream(“E:\iotest\1.txt”);
    在通过void close关闭流
    BufferedInputStream比FileInputStream读取效率更高
    12.2021/4/19
    3.IO流
  3. 写出流
    概述
    是指 从 Java程序 写出到 磁盘中 的过程
    根据写出 数据的格式不同,,可以采用字符流 字节流
    字符流 只能写出 字符数据
    字节流 可以 写出各种类型的数据 --重点!!
    读取工具类:InputStream - FileInputStream - BufferedInputStream
    写出工具类:OutputStream - FileOutputStream - BufferedOutputStream
    2.工具类
    OutputStream :是父类,被修饰成抽象类,不能new,学共性的方法
    void close()
    关闭此输出流并释放与此流有关的所有系统资源。
    void flush()
    刷新此输出流并强制写出所有缓冲的输出字节。
    void write(byte[] b)
    将 b.length 个字节从指定的 byte 数组写入此输出流。
    void write(byte[] b, int off, int len)
    将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
    abstract void write(int b)。
  • FileOutputStream :是子类,研究new
    FileOutputStream(String name)。
    创建一个向具有指定名称的文件中写入数据的输出文件流。
    FileOutputStream(String name, boolean append)
    创建一个向具有指定 name 的文件中写入数据的输出文件流。

  • BufferedOutputStream :是子类,研究new
    BufferedOutputStream(OutputStream out)
    创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
    3.通过IO流实现文件复制

      import java.io.*;
      import java.util.Scanner;
    
      //复制文件
      public class Test3 {
          public static void main(String[] args)  throws IOException {
              String from = new Scanner(System.in).nextLine();//1,源文件
              String to = new Scanner(System.in).nextLine(); //2,目标文件
              copyOf(from,to); //3,复制
              System.out.println("文件复制完成...");
          }
          //复制文件
          public static void copyOf(String from, String to)  {
              InputStream in = null;//为了finally也能用
              OutputStream out = null;//为了finally也能用
              try{
                  //1,读取from文件
                  in = new BufferedInputStream(new FileInputStream(from));
                  //2,写出to文件
                  out = new BufferedOutputStream(new FileOutputStream(to));
                  //3,读一个写一个
                  int b = 0;//定义变量,记录读到的数据
    
                  long start = System.currentTimeMillis();//计时开始ms
                  byte[] buf = new byte[8192];//模拟底层的数组容量8K
                  while( ( b = in.read(buf) ) != -1){//一个数组一个数组的读
                      out.write(buf);//一个数组一个数组的写
                  }
                  long end = System.currentTimeMillis();//计时结束ms
                  System.out.println(end-start);//97ms->2ms->0ms
              }catch (Exception e){
                  e.printStackTrace();
              }finally {
                  //TODO 改造 -- 为了保证资源一定会被释放,必须放入finally中
                  //4,关闭资源
                  try {
                      in.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  try {
                      out.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
    

1.new FileOutputStream(“E:\iotest\1.txt”,true)实现数据追加
2.in = new BufferedInputStream(System.in);通过键盘键入的是inputStream输入流
3.如果应用引用类型,没给引用类型赋值,调用引用类型的属性和方法会报空指针异常
4.包装输出流数据,先一个一个字节输出到流中,在一个数组直接输出到磁盘中,普通输出流,先一个一个字节输出到流中,在一个字节一个字节输出到磁盘中
5…包装输入流读数据,先一个一个字节读到流中,在一个数组直接读到程序中,普通输入流
先一个一个字节读到流中,在一个一个的字节读到java程序中
6.flush刷新缓冲区,close既刷新了缓冲区,也关闭了流资源

13.2021/4/20
1.泛型的通用性
1. 测试
//测试 泛型的通用性
public class Test1 {
public static void main(String[] args) {
//1,打印数组里的数据
String[] a = {“杨幂”,“周笔畅”,“Anglelababa”,“迪丽热巴”,“刘沛霞”};
print(a);
Integer[] b = {1,2,3,4,5};
print(b);
}
//泛型方法:返回值前+参数里
public static void print(E[] x){
//高效for循环/foreach循环:两个使用场景:数组Collection集合
//语法:for( 遍历得到的数据的类型 变量名 : 要遍历的是啥){循环体}
for( E s : x){
System.out.println(s);
}

	        //普通for循环
	        for (int i = 0; i < x.length; i++) {
	            System.out.println(x[i]);
	        }
	    }

	}

2.Collection接口
1.概述
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称 为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允 许。一些 collection 是有序的,而另一些则是无序的。
2.测试
//测试 Collection接口
//1,创建对象
Collection c = new ArrayList<>();
//2,调用方法
c.add(100);//添加元素,要符合泛型类型的检查
c.add(200);//自动装箱
c.add(300);
System.out.println©;
// c.clear();//清空集合
System.out.println( c.contains(200) );//判断c里是否包含200元素
System.out.println( c.equals(“jack”) );//判断c是否和"jack"相等
System.out.println( c.hashCode() );//获取哈希码值
System.out.println( c.isEmpty() );//判断c是否为空
System.out.println( c.remove(100) );//移除100元素
System.out.println( c.size() );//获取集合里元素的个数
//Object[]可以存的数据类型丰富,很通用
Object[] o = c.toArray();//把c里的数据存入Object[]
System.out.println( Arrays.toString(o) );
Object[] o2 ={null,1,1.1,“jack”};
//迭代集合中的元素
// 方式1:Iterator iterator()
Iterator it = c.iterator();
while (it.hasNext()){//hasNext()判断有没有数据
Integer data = it.next();//获取数据
System.out.println(data);
}
// 方式2: foreach的使用场景:数组|Collection集合
for (Integer z : c) {
System.out.println(z);
}

	        //集合间的操作--了解
	        Collection<Integer> c2 = new ArrayList<>();
	        c2.add(100);
	        c2.add(200);
	        System.out.println( c.addAll(c2) );//把c2加到c里
	        System.out.println(c);//[200, 300, 100, 200, 300]
	        System.out.println( c.containsAll(c2) );//判断c里包含c2吗
	//        System.out.println( c.removeAll(c2) );//移除c和c2的交集
	        System.out.println( c.retainAll(c2) );//保留c和c2的交集
	    }
	}

3.List接口
1.概述
有序,有索引,可以重复。
可以根据索引查询/插入/删除/修改
是一个Collection的子接口,可以用父接口的功能,也可以进行扩展。

2.测试

	//测试 List接口
	public class Test3 {
	    public static void main(String[] args) {
	        //1,创建对象
	        List<Integer> list = new ArrayList<>();
	        //2,调用方法
	            //继承自父接口Collection的
	        list.add(200);
	 
	        //[100, 200, 300, 100, 200, null, null]
	        //特点:有序 + 可以重复 + 可以存多个null
	        System.out.println(list)		 
	        list.add(0,10);//在指定下标位置添加新元素
	//[10, 100, 200, 300, 100, 200, null, null]
	        System.out.println( list.get(3) );//获取下标为3对应的元素
	        System.out.println( list.indexOf(200) );//获取200元素第一次出现的下标
	        System.out.println( list.lastIndexOf(200) );//获取200元素最后一次出现的下标
	        System.out.println( list.remove(1) );//移除1下标处的元素
	        System.out.println( list.set(5,666) );//把5下标处的元素换成666
	        List<Integer> list2 = list.subList(2,6);//从2开始到6结束,截取子List[2,6)

	        //移除指定的元素
	        //[10, 200, 300, 100, 200, 666, null]
	//      System.out.println( list.remove(2) );//按下标移除
	        //直接移除元素,传入基本类型的参数会当做下标用
	        System.out.println( list.remove(new Integer(300) ) );
	        //TODO 迭代List接口中元素的方式
	        //方式1:: 继承自父接口的方法Iterator<E> iterator()
	        System.out.println();
	        Iterator<Integer> it = list.iterator();
	        while (it.hasNext()){//判断有没有元素
	            Integer data = it.next();//获取元素
	            System.out.println(data);
	        }
	        //方式2:: List有下标,根据下标遍历for
	        for (int i = 0; i < list.size(); i++) {
	            Integer data = list.get(i);//根据下标获取
	            System.out.println(data);
	        }
	        //方式3:: foreach
	        for (Integer x : list) {
	            System.out.println(x);
	        }
	        //方式4:: List子接口的扩展方法ListIterator<E> listIterator()
	        ListIterator<Integer> it2 = list.listIterator();
	        //顺序遍历
	        while(it2.hasNext()){
	            Integer data = it2.next();
	            System.out.println(data);
	        }
	        //逆向遍历
	        while (it2.hasPrevious()){//判断前面有元素吗
	            Integer data = it2.previous();//获取前面的元素
	            System.out.println("data = " + data);
	        }
	        //TODO 面试题1: 数组 和集合 的区别
	        //TODO 面试题2: List接口的迭代方式
	        //TODO 面试题3: iterator()和listIterator()的区别
	        //前者是父接口Iterator提供的,后者是ListIterator子接口提供的
	        //ListIterator子接口可以使用父接口的所有功能也进行了扩展
	        //扩展了逆向遍历(必须先顺序遍历)
	    }
	}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

4.ArrayList实现类
1.概述
是List接口的实现类。拥有和List接口一样的特点。
底层是数组。
2.创建对象
ArrayList()
构造一个初始容量为 10 的空列表。
3.测试
package cn.tedu.util;

	import java.util.ArrayList;
	import java.util.Arrays;

	//测试 ArrayList接口
	public class Test4 {
	    public static void main(String[] args) {
	        //1,创建对象
	 //本质上底层会维护一个Object[] elementData,用来存放入ArrayList中的数据
	    //1,jdk1.6,当创建ArrayList对象时,底层会初始化一个数组,默认容量是10.
	        //数据多的时候,超过10个时,会自动扩容:旧容量+旧容量/2
	        //jdk1.8,但是,一开始是空数组.第一次添加数据时才开始扩充容量.扩充容量为默认容量为10

以上两者容量不够都会自动扩充其容量
ArrayList list = new ArrayList();
//2,add被调用时,拿着数据,直接存入了Object[]中.
list.add(“1”);//存入数组里的0下标处
list.add(“2”);//存入数组里的1下标处…
list.add(“3”);
list.add(“1”);
list.add(null);
//特点::有序 + 有下标 + 可重复
System.out.println(list);
//2,调用方法
//继承自Collection接口的
//继承自List接口的

	        //TODO 模拟ArrayList
	        //创建对象时,会创建Object数组并初始化
	        Object[] elementData = {};//1.8的写法
	        elementData = new Object[10];//1.6的写法
	        //add()添加数据时,把数据存入数组里
	        elementData[0] = "1";
	        elementData[1] = "2";
	        elementData[2] = "3";
	        elementData[3] = "1";
	        //数据的长度<=10,不会扩容,>10时会自动扩容,是以前的1.5倍
	        elementData = Arrays.copyOf(elementData,15);
	        elementData = Arrays.copyOf(elementData,22);

	        //TODO 练习:求List里的偶数和,奇数个数,平均值
	        //TODO 练习:求List里的最大值,最小值
	        
	    }
	}

14.2021/4/21
1.Collections工具类的使用
1.List list = new ArrayList<>();
//利用工具类,一次性向集合中添加一批数据
Collections.addAll(list,1,4,2,6,74,89,56);
2.LinkedList实现类
1.概述
是List接口的实现类。
可以使用List接口的所有方法,也可以扩展。
底层是一个链表结构,适合增删业务
LinkedList() 构造一个空列表。
Linkedlist的特点:1.允许为空2.是允许有重复数据.3.是有序4.非线程安全
System.out.println(list.get(0));//获取list的集合中第一个元素。
list.addFirst(100);//添加首元素
list.addLast(200);//添加尾元素
System.out.println(list);
System.out.println( list.getFirst() );//获取首元素
System.out.println( list.getLast() );//获取尾元素
System.out.println( list.removeFirst() );//删除首元素
System.out.println( list.removeLast() );//删除尾元素
3.Set接口
1.概述
Set接口的特点:不重复 + 无序 + 没下标 + 存一个null
Set接口继承了Collection接口,可以使用父接口的所有方法,也可以扩展 (set没扩展)
Set接口没法new,只能学习方法。
2.HashSet概述
HashSet实现了Set接口,可以使用Set接口的方法们,也可以扩展。
HashSet实现类,可以学习的是new,方法都是实现来的。
3.HashSet创建对象
HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。

4.Set去重
//给List去重
//1,准备数据
ArrayList list = new ArrayList();
Collections.addAll(list,1,2,3,1,3,4,5,6);
//准备Set集合去重
HashSet set = new HashSet();
//2,获取list里的每个数据
for(Integer data : list){
//利用了Set去重的特点
set.add(data);
}
System.out.println(set);
}
}
6.Set的测试
//测试 HashSet实现类
//1,创建对象
//HashSet创建对象时,本质上底层new了一个HashMap
HashSet set = new HashSet();
//当向set中添加数据时,本质拿着数据存入了HashMap中
//特点:不能重复 + 存一个null + 无序
//2,调用方法
//也可以去重+数组可以自然排序
TreeSet set2 = new TreeSet();
set2.add(“jack”);
set2.add(“jerry”);
set2.add(“jack”);
set2.add(“abc”);
set2.add(“bc”);
System.out.println(set2);
}
}
四,Map集合

  1. 概述
    是接口,和Collection没有继承实现的关系。
    数据是一对儿一对儿出现的。必须同时指定这组数据的K,V
    K是键,V是值。其中,K不能重复.V可以重复
    K–key ,V–value

  2. 测试

     //测试 HashMap实现类
     public class Test5 {
         public static void main(String[] args) {
             //1,创建HashMap对象
             HashMap<key的类型,value的类型> map = new HashMap();
             HashMap<Integer,String> map = new HashMap<>();
             //2,调用方法
             map.put(9527,"唐伯虎");//把一组映射关系的数据存入map
             //特点:数组无序 + key不能相同,相同时value被覆盖
             //{9520=华夫人, 9525=秋香姐, 9527=唐伯虎, 9528=如花}
             System.out.println(map);
             System.out.println( map.containsKey(9520) );//判断是否包含9520的key
             System.out.println( map.containsValue("唐伯虎") );//判断是否包含"唐伯虎"的value
             System.out.println( map.equals("唐伯虎") );//判断是否相等
     //        map.clear();//清空集合
             System.out.println(map.get(9525));//根据key获取value
             System.out.println(map.hashCode());//获取哈希码值
             System.out.println(map.isEmpty());//判断是否为空
             System.out.println(map.size());//获取map的长度
             System.out.println(map.remove(9528));//根据key删除记录
             //迭代Map集合里的数据 {9520=华夫人, 9525=秋香姐, 9527=唐伯虎}
             //方式1::Set<K> keySet()--把所有key获取到并存入set
             Set<Integer> keys = map.keySet();//把所有key存入到set里
             for (Integer k: keys) {//迭代set,得到每个key
                 //拿着key查对应的vlaue
                 String v = map.get(k);
                 //判断取到的value和"秋香姐"是否相等
                 if( v.equals("秋香姐") ){
                     System.out.println(v+",加个微信不喽~");
                 }
                 System.out.println(k+",,,"+v);
             }
             //方式2::Collection<V> values()--只能把map里的所有value取出来
             Collection<String> vs = map.values();//把map里的value们获取到
             for (String v : vs) {//迭代Collection获取每个value
                 System.out.println("v = " + v);
             }
             //方式3::Set<Map.Entry<K,V>> entrySet()
                  //把map里数据的key和value都获取到并封装成Entry存入set中
            Set<Map.Entry<Integer,String>> entrys = map.entrySet(); //迭代set,获取每个entry
            for(Map.Entry<Integer,String> entry :entrys){
                 //再获取entry封装着的key和value
                Integer k = entry.getKey();
                String v = entry.getValue();
                System.out.println(k+v);
            }
            //TODO Map的练习: 统计用户输入的字符串中的每个字符出现的次数
         }
     }
    

2021/4/22

1.HashMap
1.创建对象
HashMap()
构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
2.常用方法
同Map接口
3.测试
测试 HashMap
//1.创建对象
//使用默认的加载因子0.75(可以达到的阈值),使用默认的容量16(桶的大小)
HashMap<Integer,String> map = new HashMap();
//存数据时,先算位置.hash(key).
//判断,如果这个位置没存过数据是null的话,就把数据直接存入Node[] tab数组中
//判断,如果这个位置存过数据,会形成链表 p.next=newnode;
map.put(100,“jack”);

  1. 多线程
    1.概述
    进程是指正在运行的程序。
    线程是被包含在进程里。是操作系统能够调度的最小单位也是实际的运作单位。
    一个软件的运行需要依赖至少一个进程。
    一个进程的运行需要依赖至少一个线程。
    单线程是有1个线程,效率低。多线程拥有>1的线程数,来提高效率。
    2.线程的状态
    –刚new出来的线程是新建状态
    –可运行状态,等着CPU选中
    –运行状态,开始执行任务
    –终止状态,任务完成
    –阻塞状态,运行状态没法干完活,需要等待。等待时机到了重新回到可运行状 态。。。
    3.并发和并行的区别
    –并发是指 多个资源抢占一个CPU
    –并行是指 每个资源分配一个CPU,不用抢
    4.多线程编程
    1.Thread工具类
    –创建对象
    Thread() 分配新的 Thread 对象。
    –常用方法
    static Thread currentThread()
    返回对当前正在执行的线程对象的引用。
    long getId()
    返回该线程的标识符。
    void setName(String name)
    改变线程名称,使之与参数 name 相同。
    String getName()
    返回该线程的名称。
    void run()
    static void sleep(long millis)
    在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
    void start()
    使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
    void stop()
    已过时
    –测试

2.继承Thread
package cn.tedu.util;
//测试 模拟多线程编程
public class Test4 {
public static void main(String[] args) {
//1,启动多个线程 测试
for (int i = 0; i < 10; i++) {

	            new MyThread().start();
	            //new MyThread() --线程是新建状态
	            //start() -- 从新建状态变成可运行状态(等着CPU选中)
	        }

	        //面试题:run()和start()的区别?
	        //run()只是一个普通的方法调用,没有多线程随机的效果
	        //start()开启线程,找到线程里的业务执行
	        /*2,多线程结果的随机性:
	            Thread-0===1
	            Thread-1===1
	            Thread-6===0
	            Thread-3===0
	//1,创建多线程类--继承Thread
	class MyThread extends Thread{
	    //2,把业务放入重写的run()
	    public void run(){//使线程从可运行状态变换成运行状态
	        //需求:打印10次线程名称
	        for (int i = 0; i < 10; i++) {
	            System.out.println(super.getName()+"==="+i);
	        }
	    }//使线程从运行状态变换成 终止状态
	}

2021/4/23
1.同步锁
1. 概述
用来解决多线程编程数据安全隐患的问题
同步:实现排队的效果,不抢了
锁:把有问题的资源加锁
异步:不排队,抢
效率:异步 > 同步
安全:同步 > 异步
2. synchronized关键字
实现同步锁的效果,保证数据的安全性,牺牲了效率。
–用在方法上:synchronized public void show(){…}
–用在代码块上: 考虑 锁哪儿 + 锁谁
synchronized(锁对象){.
}
3.改造implements Runnable
//测试 多线程售票
//需求:设计4个售票窗口,总计售票100张
public class Test2 {
public static void main(String[] args) {
MyTickets target = new MyTickets();
for (int i = 0; i < 4; i++) {//利用4个线程执行同一个任务
new Thread(target).start();//target任务对象
}
}
}
//创建多线程类售票 – implements Runnable
class MyTickets implements Runnable{
int tickets = 100;
Object obj = new Object();
@Override
1,给方法加锁,实现了同步方法,保证了访问方法时必须排队等待不抢了,保证了数据安全
// synchronized public void run() {
public void run() {
while (true){
//2,给代码块加锁,实现同步代码块,实现了访问代码块要排队等待的效果
//锁哪儿–从共享资源被第一次使用开始,到用完结束

	                if (tickets > 0) {
	                    try {
	                        Thread.sleep(10);
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }
	                    System.out.println(Thread.currentThread().getName() + "~~" + tickets--);
	                } else {
	                    break;
	                }
	            }
	
4.改造extends Thread
	package cn.tedu.util;
	//测试 多线程售票
	//需求:设计4个售票窗口,总计售票100张
	public class Test1 {
	    public static void main(String[] args) {
	        for (int i = 0; i < 4; i++) {//用4个线程模拟4个窗口
	            new MyTicket().start();//启动线程
	        }
	    }
	}
	//创建多线程类售票 -- extends Thread
	class MyTicket extends Thread{
	    static int tickets = 100;
	    //2,方法可以被同步修饰,普通方法,会自动分配this对象
	                        //静态方法,会自动分配类名.class对象
	    public void run() {
	        while(true){
	       //1,锁对象是谁?--如果共享资源是普通资源,锁对象可以任意
	                    //--如果共享资源是静态资源,锁对象必须是类名.class
	           synchronized (MyTicket.class){
	                if (tickets > 0) {
	                    try {
	                        Thread.sleep(10);
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }
	                    System.out.println(super.getName() + "==" + tickets--);
	                } else {
	                    break;//结束死循环
	                }
	            }
	        }
	    }
	}

	
	package cn.tedu.util;//测试 多线程售票
	//需求:设计4个售票窗口,总计售票100张
	public class Test2 {
	    public static void main(String[] args) {
	        MyTickets target = new MyTickets();
	        for (int i = 0; i < 4; i++) {//利用4个线程执行同一个任务
	            new Thread(target).start();
	        }
	    }
	}
	//创建多线程类售票 -- implements Runnable
	class MyTickets implements Runnable{
	    int tickets = 100;
	    Object obj = new Object();
	    @Override
	//    synchronized public void run() {
	    public void run() {
	        while (true){

	            synchronized ("hello"){//可以
	            synchronized (this){//可以
	            synchronized (new Object()){//不可以
	            synchronized (obj){//可以
	                if (tickets > 0) {
	                    try {
	                        Thread.sleep(10);
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }
	                    System.out.println(Thread.currentThread().getName() + "~~" + tickets--);
	                } else {
	                    break;
	                }
	            }
	        }
	    }
	}

2.线程池
–1,概述
用来存放就绪状态的线程,提高线程的高可用。
两个过程:取出去 + 还回池里
–2,工具类
Executors:创建线程池
static ExecutorService newFixedThreadPool(int nThreads)
ExecutorService:执行target
void execute(Runnable command) 在未来某个时间执行给定的命令。
3.改造
package cn.tedu.util;

	import java.util.concurrent.ExecutorService;
	import java.util.concurrent.Executors;

	//测试 多线程售票
	//需求:设计4个售票窗口,总计售票100张
	public class Test2 {
	    public static void main(String[] args) {
	        MyTickets target = new MyTickets();
	        //线程池:线程复用高 + 托管
	        //1,创建 拥有固定大小的 线程池
	        ExecutorService pool = Executors.newFixedThreadPool(4);
	        for (int i = 0; i < 2; i++) {//利用4个线程执行同一个任务
	//            new Thread(target).start();//被线程池代替
	            //2,利用池里的线程执行目标任务
	            pool.execute(target);
	        }
	    }
	}

线程池中的线程调用run具有随机性
//创建多线程类售票 – implements Runnable
class MyTickets implements Runnable{
int tickets = 100;
Object obj = new Object();
@Override

	//    synchronized public void run() {
	    public void run() {
	        while (true){

	//            synchronized ("hello"){//可以
	//            synchronized (this){//可以
	//            synchronized (new Object()){//不可以
	            synchronized (obj){//可以
	                if (tickets > 0) {
	                    try {
	                        Thread.sleep(10);
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }
	                    System.out.println(Thread.currentThread().getName() + "~~" + tickets--);
	                } else {
	                    break;
	                }
	            }
	        }
	    }
	}

3.设计模式
1.概述
Java里只有23种设计模式。就是一套代码经验的总结。
单例模式:保证一个类仅有一个实例。
2.饿汉式
package cn.tedu.design;
//测试 单例模式–一个类仅有一个实例
public class Test3 {
public static void main(String[] args) {
// new Person();
Person p = Person.get();
Person pp = Person.get();
//比了地址值,相同对象得到true
System.out.println(p == pp);
//== 和 equals()的区别???
//比较引用类型间的地址值,比较基本类型的值本身
//equals()默认就是
比,可以重写成比属性值
}
}
//饿汉式
class Person{
//1,不让外界new–私有化构造方法
private Person(){}
//2,自己new一个给外界准备着
//加static ,想要被静态的方法get()调用成功,p必须也得是静态的
static private Person p = new Person();
//3,提供一个方法,返回p
//加static ,get()不能通过对象调用,可以直接利用类名调用
static public Person get(){
return p;//把自己创建好的对象返回
}
}

5.懒汉式
	package cn.tedu.design;
	//测试 单例模式--一个类仅有一个实例
	public class Test4 {
	    public static void main(String[] args) {
	        Student a = Student.get();
	        Student b = Student.get();
	        System.out.println( a == b);
	    }
	}
	//懒汉式 -- 按需加载 -- 线程安全的解决方案
	class Student{
	    //1,私有化构造方法
	    private Student(){}
	    //2,给外界new一个
	//共享资源被多条语句操作了,一定有安全隐患--需要加锁
	    static private Student s ;
	    //3,给外界返回s --按需加载
	    //静态的同步方法,自动分配的锁对象是类名.class
	    synchronized static public Student get(){
	//        静态资源的锁对象必须是类名.class
	//        synchronized (Student.class) {
	            if (s == null) {//没new过才new
	                s = new Student();
	            }
	            return s;
	//        }
	    }
	}

6.注解
1.概述
用来减少代码,标志@。英文是Annotation
分为 jdk提供的(@Override)/元注解(@Target/@Retention)/自定义 三类
2.元注解
–@Target:::指定注解的位置
ElementType.Method–出现在方法上
ElementType.Field–出现在成员变量上
ElementType.TYPE–出现在成员类上
–@Retention:::指定注解的生命周期
RetentionPolicy.Source–源文件中有效
RetentionPolicy.CLASS–.class文件中有效
RetentionPolicy.Runtime–运行时还有效
3.自定义注解

	//测试 注解
	public class Test5 {
	    public static void main(String[] args) {

	    }
	}
	//第一步:创建注解 @interface 注解名  -----了解!
	@Target(ElementType.TYPE)//描述注解的出现位置
	@Retention(RetentionPolicy.CLASS)//描述注解的生命周期
	@interface Controller{
	}
	//第二步:使用注解 @注解名  -----必会!
	@Controller //可以用
	class Demo{
	//    @Controller//位置不对,不能用
	    String name;
	//    @Controller//位置不对,不能用
	    public void show(){
	        System.out.println(1);
	    }
	}

2021/4/25
1.注解
1.代码
package cn.tedu.annotation;

	import java.lang.annotation.ElementType;
	import java.lang.annotation.Retention;
	import java.lang.annotation.RetentionPolicy;
	import java.lang.annotation.Target;

	//测试 注解
	public class Test1 {
	    public static void main(String[] args) {

	    }
	}
	//第一步:定义注解
	@Target({ElementType.TYPE , ElementType.LOCAL_VARIABLE})//出现位置
	@Retention(RetentionPolicy.CLASS)//生命周期(超过其给定的生命周期则失效)
	@interface Mapper{
	    //添加属性
	    String local() default "";//给属性设置默认值
	    String value() default "";//给属性设置默认值,是一个特殊的属性
	    //value="jack"里的value=可以不写
	}
	//第二步:使用注解
	//@Mapper(local="type")//value使用默认值,local使用type
	//@Mapper("jack")//local使用默认值,value使用jack(可以简写)
	@Mapper(local="type",value="jack")//local使用type,value使用jack
	class AnnotationDemo{
	    String name;
	    public void show( int a){
	        @Mapper//使用local的默认值
	        int age = 10;
	    }
	}

2.反射
1.概述
通常是底层离不开的技术,用来解析.class文件里的所有资源。包括:构造方法/成 员变量/方法/注解…
利用Class工具类提供的各种方法,获取各种资源。
2.Class工具类
–创建对象
Class.forName(“类名”)
类名.class
类的实例.getClass()
3.创建Student类
package cn.tedu.reflection;
//测试 反射
public class Person {
//TODO Fileds --getFields()
public String name;
public int age;
//TODO Constructors–getConstructors()
public Person() { }
public Person(String name) {
this.name = name;
}
public Person(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//TODO Methods–getMethods()
public void show(int a,String b){
System.out.println(a);
System.out.println(b);
}
public void test(){
System.out.println(2);
}
}

4.反射类里的资源
	
	package cn.tedu.reflection;
	import java.lang.reflect.Constructor;
	import java.lang.reflect.Field;
	import java.lang.reflect.Method;
	import java.util.Arrays;

	//测试 反射Person文件
	public class Test3 {
	    public static void main(String[] args) throws ClassNotFoundException {
	//        method();//获取Class对象
	//        method2();//获取包名、类名
	//        method3();//获取 所有构造方法们~
	//        method4();//获取 所有方法们~
	        method5();//获取 所有属性们~
	    }
	    //获取 所有的属性/成员变量们~
	    private static void method5() throws ClassNotFoundException {
	        //1,获取Class对象
	        Class c = Class.forName("cn.tedu.reflection.Person");
	        //2,使用Class的方法--只能获取public的
	        Field[] fs = c.getFields();
	        //遍历数组,获取每个变量f
	        for (Field f : fs) {
	            System.out.println( f.getName() ); //获取变量名
	            System.out.println( f.getType().getName() );//获取变量类型
	        }
	    }
	    //获取 所有的方法们~
	    private static void method4() {
	        //1,获取Class对象
	        Class c = Person.class;
	        //2,使用Class的方法getMethods()--获取自己的和父类的-只能获取public的
	        Method[] ms = c.getMethods();
	        //遍历数组,获取每个方法
	        for(Method m : ms){
	            //获取方法名
	            System.out.println( m.getName() );
	            //获取参数的类型
	            Class[] cc = m.getParameterTypes();
	            System.out.println( Arrays.toString(cc) );
	        }
	    }
	    //获取 所有的构造方法们---getConstructors()
	    private static void method3() {
	        //1,获取Class对象
	        Class c = Person.class;
	        //2,使用Class的方法getConstructors()--只能获取public的
	        Constructor[] cs = c.getConstructors();
	        //遍历数组,获取每个构造方法co
	        for(Constructor co : cs){
	            //获取名字
	            System.out.println( co.getName() );
	            //获取参数类型
	            Class[] cs2 = co.getParameterTypes();
	            System.out.println( Arrays.toString(cs2) );
	        }
	    }
	    //获取包名、类名
	    public static void method2() {
	        //1,获取Class对象
	        Class c = Person.class;
	        //2,使用Class的方法
	        System.out.println( c.getSimpleName() );//类名
	        System.out.println( c.getPackage().getName() );//包名
	        System.out.println( c.getName() );//全路径名
	    }
	    //获取Class对象
	    public static void method() throws ClassNotFoundException {
	        Class c1 = Class.forName("cn.tedu.reflection.Person");
	        Class c2 = Person.class;
	//        Class c3 = new Person().getClass();
	    }
	}

3.反射的高级用法
package cn.tedu.reflection;

	import java.lang.reflect.Constructor;
	import java.lang.reflect.Field;
	import java.lang.reflect.Method;

	//反射的高级用法
	public class Test4 {
	    public static void main(String[] args) throws Exception {
	//        method();//反射创建对象
	//        method2();//反射操作属性
	        method3();//反射操作方法
	    }
	    //反射操作方法
	    private static void method3() throws Exception {
	        //1,获取class对象
	        Class c = Person.class;
	        //2,利用反射执行方法
	        //获取指定的方法
	        //getMethod(1,2)--1是方法名2是参数类型的class对象
	        //public void show(int a,String b){}
	        Method m = c.getMethod("show",int.class,String.class);
	        Object obj = c.newInstance();
	//Object invoke(1,2)--1是要执行哪个对象的方法--2是调用方法时要传入的具体参数
	        m.invoke(obj,10,"tony");//执行方法
	    }
	    //反射操作属性
	    private static void method2() throws Exception {
	        //1,获取class对象
	        Class c = Person.class;
	        //2,利用反射set/get
	        Field f = c.getField("age");
	        //set(1,2)--1是要给哪个对象设置值--2是要设置的具体值是啥
	        Object obj = c.newInstance();
	        f.set(obj, 100);//给属性设置值
	        //get(1)--1是要获取哪个对象的值
	        System.out.println(f.get(obj));//获取属性值
	    }
	    //反射创建对象--newInstance()
	    private static void method() throws Exception {
	        //1,获取class对象
	        Class c = Person.class;
	        //2,利用反射new -- newInstance()
	        Object o = c.newInstance();//会调用 无参的构造方法
	        System.out.println(o);//cn.tedu.reflection.Person@1b6d3586
	        //3,获取 要调用 含参 构造方法
	        //getConstructor()参数是含参构造需要的参数类型的class对象
	       Constructor con = c.getConstructor(String.class);
	       //newInstance()参数是要触发含参构造时,想要具体指定的参数值
	       Object o2 = con.newInstance("jack");
	       System.out.println(o2);
	       //调用Person的资源
	       Person p = (Person) o2;//向下转型,就是用子类的功能
	       p.test();
	       p.show(10,"x");
	    }
	}

2021/4/26
1.反射
1.需求
–准备类(public/private/default)
–获取类里成员变量(getField)并set()/get()
–获取类里普通方法(getMethod)并执行方法(invoke)
–获取类里构造方法(getConstructor)并new对象(newInstance)
2.创建Human类
package cn.tedu.reflection;
//测试 反射
public class Human {
//TODO Fields
public String name;
public int age;
double salary;
//TODO Constructors
public Human() { }
public Human(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
//TODO Methods
public void test1(){
System.out.println(1);
}
private void test2(String a){
System.out.println(a);
}
void test3(int a){
System.out.println(a);
}
}

3.创建测试类
	package cn.tedu.reflection;

	import java.lang.reflect.Constructor;
	import java.lang.reflect.Field;
	import java.lang.reflect.InvocationTargetException;
	import java.lang.reflect.Method;

	//测试 反射
	public class Test1 {
	    public static void main(String[] args) throws Exception {
	//        method();//反射操作成员变量
	//        method2();//反射操作成员方法
	//        method3();//反射操作构造方法
	    }
	    //反射操作构造方法
	    private static void method3() throws IllegalAccessException, InvocationTargetException, InstantiationException {
	        //1,获取Class对象
	        Class c = Human.class;
	        //2,获取构造方法
	        Constructor[] a = c.getConstructors();
	        //遍历数组,得到每个构造方法con
	        for (Constructor con : a) {
	            Class[] cc=con.getParameterTypes();
	            if(cc.length==0){//无参构造
	                Object o = con.newInstance();
	                System.out.println(o);
	            }
	            if(cc.length!=0){//含参构造
	 Object o = con.newInstance("tony",20,10000);
	                System.out.println(o);
	            }
	        }
	    }
	    //反射操作成员方法
	    private static void method2() throws Exception, InstantiationException {
	        //1,获取Class对象
	        Class c = Human.class;
	        //2,获取成员方法
	        Method[] a = c.getMethods();
	        //遍历数组,获取每个方法
	        for (Method m : a) {
	            System.out.println(m.getName());
	            //只执行test1()
	            if(m.getName().equals("test1")){
	                Object obj = c.newInstance();
	                m.invoke(obj);//执行方法
	            }
	        }
	    }
	    //反射操作成员变量
	    private static void method() throws IllegalAccessException, InstantiationException {
	        //1,获取Class对象
	        Class c = Human.class;
	        //2,获取成员变量
	        Field[] a = c.getFields();
	        //遍历数组,得到每个变量f
	        for (Field f : a) {
	            //获取属性名 
	            System.out.println(f.getName());
	            //3,只对name属性进行set/get
	            if(f.getName().equals("name")){
	                Object obj = c.newInstance();
	                f.set(obj,"jack");//设置属性值
	                System.out.println(f.get(obj));//获取属性值
	            }
	        }
	    }
	}

4.注解 + 反射
package cn.tedu.reflection;

	import java.lang.annotation.ElementType;
	import java.lang.annotation.Retention;
	import java.lang.annotation.RetentionPolicy;
	import java.lang.annotation.Target;
	import java.lang.reflect.Method;

	//反射有注解的类,并new
	public class Test2 {
	    public static void main(String[] args) throws Exception {
	        //TODO 3,解析注解 --框架完成!
	       //1,获取Class对象
	        Class c = Demo.class;
	       //2,获取所有方法
	        Method[] a = c.getMethods();
	        //遍历数组,得到每个方法m
	        for (Method m : a) {
	            //获取方法上指定的注解(保证注解运行时还有效)
	            Controller con = m.getAnnotation(Controller.class);
	            //3,判断,方法有注解才执行
	            if(con != null){
	                //4,只执行使用了注解的方法
	                Object obj = c.newInstance();
	                m.invoke(obj);
	            }
	        }
	    }
	}
	//1,定义注解 --框架完成!
	@Target(ElementType.METHOD)//注解可以出现在方法上
	@Retention(RetentionPolicy.RUNTIME)//注解可以存在的时间
	@interface Controller{
	}
	//2,使用注解 --重点!!
	class Demo{
	    String name="jack";
	    @Controller
	    public void method(){
	        System.out.println(123);
	    }
	    @Controller
	    public void method2(){
	        System.out.println(321);
	    }
	}

2.暴力反射
1.概述
可以获取.class文件里的所有资源(包括:public/default/private)
–普通反射:只能获取public的
getMethods()
getMethod()
getFields()
getField()
getConstructors()
getConstructor()
–暴力反射:所有的
–用对API + 有足够的权限
getDeclaredMethods()
getDeclaredMethod()
getDeclaredFields()
getDeclaredField()
getDeclaredConstructors()
getDeclaredConstructor()
setAccessible(true) – 一切资源都可以操作
2.改造Human类
package cn.tedu.reflection;
//测试 反射
public class Human {
//TODO Fields
public String name;
private int age;
double salary;
//TODO Constructors
public Human() { }
public Human(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
//TODO Methods
public void test1(){
System.out.println(1);
}
private void test2(String a){
System.out.println(a);
}
void test3(int a){
System.out.println(a);
}
}
3.创建测试类
package cn.tedu.reflection;

	import java.lang.reflect.Field;
	import java.lang.reflect.Method;

	//测试 暴力反射
	//要求:用对API + 要有权限
	//优点:比普通的反射,可以获取到更多的资源,不知public的,甚至default 			private都可以
	public class Test3 {
	    public static void main(String[] args) throws Exception {
	//        method();//所有方法
	        method2();//所有属性
	    }
	    //所有属性
	    private static void method2() throws Exception {
	        Class c = Human.class;
	//        c.getFields();//只能获取public的
	        //暴力反射
	        Field[] a = c.getDeclaredFields();
	        for (Field f : a) {
	            //对public的属性get/set
	            Object obj = c.newInstance();
	            if(f.getName().equals("name")){
	                f.set(obj,"张三");
	                System.out.println(f.get(obj));
	            }
	            //对private的属性get/set--开启权限
	            if(f.getName().equals("age")){
	                //有权限
	                f.setAccessible(true);
	                f.set(obj,666);
	                System.out.println(f.get(obj));
	            }
	        }
	    }
	    //所有方法
	    private static void method() throws Exception {
	        Class c = Human.class;
	//        Method[] a = c.getMethods();//只能获取public的
	        //暴力反射--public /default/private
	        Method[] a = c.getDeclaredMethods();
	        for (Method m : a) {
	            Object obj = c.newInstance();
	            //只执行test1
	            if(m.getName().equals("test1")){
	                m.setAccessible(true);
	                m.invoke(obj);
	            }
	            //暴力反射想执行private /default的
	            if(m.getName().equals("test2")){
	   //开启权限,否则操作私有资源会抛异常IllegalAccessException
	                m.setAccessible(true);
	                m.invoke(obj,"hello java");
	            }
	        }
	    }
	}

3.内部类
1.概述
是指 把一个类放入另一个类里面 的形式
好处:安全性高,节省内存
内部类根据出现的位置不同,分为3 种
–成员位置(类里方法外)的内部类,叫成员内部类
–局部位置(方法里)的内部类,叫局部内部类
–匿名内部类:位置是在局部位置,通常配合匿名对象一起用
2.成员内部类
package cn.tedu.inner;
//测试 内部类
public class Test4 {
public static void main(String[] args) {
A.B a = new A().new B();//3,内部类的对象
a.in();//使用内部类的资源in()
//7,使用静态的内部类的资源
System.out.println( new A.D().d );
System.out.println( A.D.m );
}
}
class A{//外部类
String name = “jack”;
public void out(){
//2,外部类使用内部类的资源age --必须创建内部类的对象
System.out.println(new B().age);
System.out.println(“out…”);
//5,间接的访问C里的资源
System.out.println(new C().b);
}
//6,成员内部类:被static修饰
static class D{
String d = “tony”;
static int m = 10;
}
//4,成员内部类:被private修饰
private class C{
double b = 10;
}
//成员内部类:看作是外部类的成员
class B{
int age = 20;
public void in(){
//1,内部类使用外部类的资源name --直接用
System.out.println(name);
System.out.println(“in…”);
}
}
}

3.匿名内部类	
	--测试1
		package cn.tedu.inner;
		//测试 匿名内部类 --在方法里 --优化了设计结构
		public class Test5 {
		    public static void main(String[] args) {
		        //3,测试接口
		//        AA a = new AA();//接口不能实例化
		//        AA a = new BB();//多态对象,用来统一调用标准,向左边看齐
		//        a.save();
		        //4,匿名内部类配合匿名对象一起用--好处是优化了结构
		        new AA(){//直接new接口,在内部类里重写抽象方法
		            @Override
		            public void save(){
		                System.out.println(123);
		            }
		        }.save();//调用方法
		        //TODO 5,练习匿名内部类
		        X x = new X(){
		            @Override
		            public void del(int id) {
		                System.out.println(id);
		            }
		            @Override
		            public void get() {
		                System.out.println(100);
		            }
		        };
		        //匿名对象,一次只执行一个任务。想用用一个对象执行很多任务。
		        x.get();//调用方法
		        x.del(10);
		    }
		}
		//TODO 5,练习匿名内部类
		interface X{
		    void del(int id);
		    void get();
		}
		interface AA{
		    //1,接口里都是抽象方法,可以简写
		//    public abstract  void save();
		    void save();
		}

2021/4/27
1.socket编程
1.概述
也叫网络编程,用来解决 网络间数据传输 的需求
必须知道 对方的ip和 端口号
socket的本质是,把数据抽象成IO流在网络里 读写
2.工具类
–服务器端ServerSocket
–创建对象:ServerSocket(int port)
–常用方法:Socket accept() 侦听并接受到此套接字的连接
void close() 关闭此套接字
–客户端Socket
–创建对象:Socket(String host, int port)
–常用方法:void close() 关闭此套接字
InputStream getInputStream() 返回此套接字的输入流。
OutputStream getOutputStream() 返回此套接字的输出流。
3.测试
–需求:客户端给服务发出hello,服务器发回来world
–服务器:
package cn.tedu.net;

		import java.io.IOException;
		import java.io.InputStream;
		import java.io.OutputStream;
		import java.net.ServerSocket;
		import java.net.Socket;

		//代表服务器端IO
		//职责:读客户端发来的数据,给客户端写出数据
		public class Server {
		    public static void main(String[] args) throws IOException {
		        //1,创建对象 -- 端口号:1025~65535
		        ServerSocket server = new ServerSocket(8000);
		        System.out.println("服务器已启动..");
		        //2,接收客户端发来的连接请求--侦听并接受到此套接字的连接
		        Socket socket = server.accept();
		        System.out.println("服务器收到一个连接请求...");
		        //3,读取 客户端发来的数据 --in
		        InputStream in = socket.getInputStream();
		        for (int i = 0; i < 5 ; i++) {
		            int b = in.read();
		     //问题:read()默认返回值类型是int,现在要char--int->char--强转
		            char c = (char)b;
		            System.out.println(c);
		        }
		        //4,给客户端写出数据--out
		        OutputStream out = socket.getOutputStream();
		        //问题:字节流不能写出字符串--String->byte[]--getBytes()
		        out.write("world".getBytes());
		        out.close();
		    }
		}


	客户端:
		package cn.tedu.net;

		import java.io.*;
		import java.net.Socket;

		//代表服客户端IO
		//职责:读服务器发来的数据,给服务器写出数据
		public class Client {
		    public static void main(String[] args) throws IOException {
		        //1,连接服务器 -- 服务器的ip和端口号
		        Socket socket = new Socket("127.0.0.1",8000);
		        System.out.println("客户端与服务器连接成功..");
		        //2,给服务写出hello --out
		        OutputStream out = socket.getOutputStream();
		        //问题:字节流不能写出字符串 -- String->byte[]--getBytes()
		        out.write("hello".getBytes());
		//        out.close();//把socket底层用的流关了
		        out.flush();//只刷出去数据不关流
		        //3,读取数据--in
		        InputStream in = socket.getInputStream();
		        for (int i = 0; i < 5; i++){
		           //问题:read()默认返回的是int类型,想变成char--强转
		            char c = (char)in.read();
		            System.out.print(c);
		        }
		    }
		}

2.正则表达式
1.概述
用来约束字符串的正确规则regex
2.语法
[0-9]–表示出现0-9范围的数据,只能出现1次
[a-z]–表示出现26个小写字母范围的数据,只能出现1次
[A-Z]–表示出现26个大写字母范围的数据,只能出现1次
{n}–表示出现固定的次数
3.常用方法
String.matches(String regex)–判断字符串是否匹配正则表达式的要求
4.测试
package cn.tedu.util;

	import java.util.Scanner;

	//测试 正则表达式
	public class Test1 {
	    public static void main(String[] args) {
	        //1,接受用户输入的字符串
	        String input = new Scanner(System.in).nextLine();

	        String regex = "1[0-9]{10}" ;  //2,判断是否是手机号码的格式
	        regex = "[1-9]{17}[0-9X]" ;//3,判断是否是身份证号码的格式
	        //判断字符串是否匹配正则表达式的要求
	        if(input.matches(regex))
	            System.out.println("ok");
	        else
	            System.out.println("no ok");
	    }
	}

3.可变参数
package cn.tedu.util;

		import java.util.Arrays;

		//jdk5...可变参数
		public class Test2 {
		    public static void main(String[] args) {
		        print(1);
		        print(1);
		        print(1,2);
		        print(1,2,3,4,5);
		    }
		    //可变参数... 是指参数的个数可变
		    private static void print(int b,int... a) {
		        //本质上就是一个数组,动态匹配参数的个数
		        //参数列表里,如果有可变参数,位置必须是最后一个
		        System.out.println(a);//[I@1b6d3586
		        System.out.println(Arrays.toString(a));
		    }
		}

4.catch 多个类型异常
import java.io.*;
//jdk7的新特性:自动资源管理 | catch 多个类型异常
public class Test3 {
public static void main(String[] args) {
// method();//close释放资源
method2();//优化后
}
//优化后:把对象的声明放在try的小括号里,用完了就自动释放
private static void method2() {
try(InputStream in = new BufferedInputStream(
new FileInputStream("??"));
){
int data = in.read();
System.out.println(data);
}catch(NullPointerException | IOException f){
//jdk7的新语法:一次性catch 多个类型异常
f.printStackTrace();
}
}
//IO读取数据
private static void method() {
InputStream in = null;
try{
in = new BufferedInputStream(
new FileInputStream("??"));
int data = in.read();
System.out.println(data);
}catch(NullPointerException | IOException f){
//jdk7的新语法:一次性catch 多个类型异常
f.printStackTrace();//开发调试阶段用
// System.out.println(“读取失败”);//项目上线时用
}finally{//保证代码一定要执行
if(in != null){
try{
in.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}

5.Lambda表达式
package cn.tedu.util;
//jdk8的Lambda表达式
public class Test4 {
public static void main(String[] args) {
// V1.0 测试
// A a = new B();
// a.save();
// V2.0 匿名内部类 – 优化了程序的设计结构
// A a = new A(){
// @Override
// public void save() {
// System.out.println(“save…”);
// }
// };
// a.save();

		        // V3.0 Lambda --优化匿名内部类(只能有一个抽象方法)
		        //语法: (参数列表)->{方法体}
		        A a = ()->{ System.out.println("save.."); };
		        a.save();
		        //TODO 练习 Lambda表达式
		        B b = (int m)->{  System.out.println(m);  };
		        b.get(10);
		        C c = (int x,String y)->{
		            System.out.println(x);
		            System.out.println(y);
		        };
		        c.del(1000,"tony");
		    }
		}
		//TODO 练习 Lambda表达式
		interface C{
		    void del(int id,String name);
		}
		interface B{
		    void get(int id);
		}
		//定义接口
		interface A{
		    void save();
		}
		//实现类接口
		//class B implements A{
		//    @Override
		//    public void save() {
		//    }
		//}

6.复习
1.OOP
–封装:用private实现,被封装后只能在本类中访问。
–继承:好处是可以提高父类代码的复用性,减少子类代码的编写。
–class A extends B{}
–子类可以使用父类的所有功能(除了private的/构造方法)
–子类可以扩展自己的特有方法
–子类还可以修改父类的功能(方法重写),对于原有功能不许影响
–重写的语法要求:方法声明必须和父类一样 + 有足够的权限
–多态:好处是统一调用的标准,向父类看齐 + 增强通用性
–class Dog extends Animal{}
–父类引用 指向子类对象 + 编译看左边,运行看右边
–Animal a = new Dog();//只能用父类的功能
–非得用子类的扩展的功能:直接new一个子类对象 + 向下转型
–抽象类和接口:
–接口是一个特殊的抽象类,接口里都是抽象方法,抽象类里可以有普通的和 抽象的方法
–程序设计上:接口(灵活,可以多继承多实现) > 抽象类(只能单继承)
–接口里没有构造方法,抽象类里有(为了给子类new)
–接口里没有变量都是常量(可以简写),抽象类里有变量也有常量(不能简写)
–public static final int age = 10;
–public abstract void save();
–2,Collection
–数组和集合的区别?
–数组存的数据类型单一/长度固定/只适合查询
–ArrayList和LinkedList的区别?
–ArrayList底层是数组,适合查
–LinkedList底层是链表,适合增删
–List接口的迭代方式有几种?
–iterator()/listIterator()/普通for/foreach
–iterator()/listIterator()的区别?
–iterator()是父接口Collection提供的,返回父接口Iterator
–listIterator()是子接口Listn提供的,返回子接口ListIterator
–除了能用父接口的所有功能,还扩展了(逆向遍历)
–HashMap原理?
–底层数组 + 链表(红黑树)
–3,IO
–out是写出流,是把程序中的数据 写出到 磁盘
–in是读取流,是把磁盘中的数据 读取到 程序
–效率上:BufferedInputStream(底层有缓存数组8192) > FileInputStream
BufferedOutputStream(底层有缓存数组8192) > FileOutputStream
–BufferedInputStream 和 FileInputStream的区别?主要是效率的区别
–close()/flush()的区别?
–flush():只负责把数据从out流里刷出去
–close():把数据从out流里刷出去 + 关闭资源

  1. instanceof 关键字
    if(A instanceof B){
    System.out.println(“A是B的子类,或A是B的实例,满足其条件执行输出语句”);
    2021/5/6
    1.作业扩展
    //创建RandomAccessFile对象对数据进行读写,读出的信息封装给Emp
    private static Emp paseEmp(File file1) throws Exception {
    RandomAccessFile ras = new RandomAccessFile(file1,“rw”);
    byte[] bytes = new byte[(int)file1.length()];
    int len = ras.read(bytes);
    String s = new String(bytes,0,len);
    String[] str = s.split(",");
    Emp emp = new Emp(str[0],Integer.parseInt(str[1]),str[2],Integer.parseInt(str[3]),new SimpleDateFormat(“yyyy-MM-dd”).parse(str[4]));
    return emp;
    }

}

	public static void main(String[] args) throws Exception {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入内容:exit为退出!");
		RandomAccessFile ras =new RandomAccessFile("1.txt", "rws");
		while(true) {
			String str = scanner.nextLine();
			if(str.equals("exit")) {
				break;
			}
			ras.write(str.getBytes());
		}
		System.out.println("写入完毕呵呵!");
		ras.close();
	}

//使用类加载器加载当前包中的emp.dat文件

  1. File file = new File(Test13.class.getClassLoader().getResource(“emp.dat”).toURI());
    getResource中路径的选择
    idea中的路径
    System.out.println(Test13.class.getClassLoader().getResource(""));
    结果集
    file:/E:/software/idea/workspace/out/production/workspace/
    File file = new File(Test13.class.getClassLoader().getResource(“src/main/java/emp.dat”).toURI());
    相应的路径为:
    file:/E:/software/idea/workspace/out/production/workspace/src/main/java/emp.dat
  2. 输出相应的文件路径
    System.out.println(TestMain.class.getResource(""));
    System.out.println(TestMain.class.getResource("/"));
    结果
    file:/E:/workspace/Test/bin/testpackage/
    file:/E:/workspace/Test/bin/
  3. 输出相应的文件路径
    TestMain.class.getResource("/") == t.getClass().getClassLoader().getResource("")
    这两者输出的结果集
    file:/E:/workspace/Test/bin/
  4. Class.getClassLoader().getResource和Class.getClassLoader().getResourceAsStream在使用时,路径选择上也是一样的。

//获得本地路径,本地路径为E:\software\idea\workspace
//如果是文件则E:\software\idea\workspace\1.txt
File file = new File(".");
///
String[] str1 = str.split("\.");转换成字符数组时.需要加上转义字符

Date date = sif.parse(str);
Calendar c =Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DAY_OF_YEAR, day);//day所增加的天数
c.add(Calendar.DAY_OF_YEAR, -14);//对应的天数-14天
c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);//设置为本周的周三
date = c.getTime();//获得当前时间,返回date对象
System.out.println(sif.format(date));
/
List list = new ArrayList();
Collections.addAll(list, “1”," " , " 2 " , " ","2"," ","2","",“3”,"KaTeX parse error: Expected '}', got 'EOF' at end of input: …if(str.equals("")) {
//可以一边迭代一边删除
iterator.remove();
}
}

for (String string : list) {
System.out.println(string);
}
输出的结果为
[1,2,3,4]

//将集合list转化为数组,数组类型和list元素类型一致否则报数组存储异常错误
Emp[] e = list.toArray(new Emp[list.size()]);
/

Queue queue = new LinkedList<>();
for (int i = 1; i <= 5; i++) {
queue.offer(i);
}

for (Integer integer : queue) {
System.out.println(integer);
}
//创建一个队列,并对这个队列进行输出
结果集为(先进先出)
1,2,3,4
//
public class Test02 {

public static void main(String[] args) {
Deque stack = new LinkedList<>();
for (int i = 1; i <= 5; i++) {
stack.push(i);
}

while(stack.size()>0) {
      System.out.println(stack.pop());
}
}

}
//创建一个栈
结果集(先进后出)
5,4,3,2,1

/
输入流的默认路径E:\software\idea\workspace
FileInputStream src = new FileInputStream(“myfile.txt.txt”);
其中注意文件的后缀

OutputStream os = null;
ObjectOutputStream oos =null;
//通过对象输出流把emp对象输出到给定的文件中
for (Emp emp : emps) {
os = new FileOutputStream(emp.getName()+".obj");
oos = new ObjectOutputStream(os);
oos.writeObject(emp);
}
oos.close();
//
序列化:把对象写入到指定的文件中
反序列化:读取相应的文件,把文件内容转化为相应的对象(前提是该文件中存入的是对象的地址信息)
//
//获得本地路径,本地路径为E:\software\idea\workspace
//如果是文件则E:\software\idea\workspace\1.txt
File file = new File(".");
//读取所有后缀为obj的文件
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.getName().endsWith(".obj");
}
});
//文件过滤器,过滤出所需的文件,返回File数组

///
//对得到的list集合按照员工薪资的升序排序
Collections.sort(list, new Comparator() {
@Override
public int compare(Emp emp1, Emp emp2) {
return emp1.getSalary()-emp2.getSalary();
}
});
//
File.separator()获得一个反斜杠

Scanner scanner = new Scanner(System.in);
System.out.println(“请输入文件名:”);
String fileNme = scanner.nextLine();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileNme),“GBK”));//缓冲字符输出流PrintWriter
while (true){
String line = scanner.nextLine();
if(line.equals(“exit”)){
break;
}
pw.println(line);
}
System.out.println(“完成文件数据输入”);
pw.close();
//PrintWriter给指定的文件输入数据
/
public class Test08 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile(“raf.dat”,“rw”);
raf.writeInt(Integer.MAX_VALUE);
raf.writeLong(Long.MAX_VALUE);
raf.seek(0);//设置从下一个地方开始读或写
int i = raf.readInt();
long l = raf.readLong();
System.out.println(“int:”+i);
System.out.println(“long:”+l);
raf.close();
}
}
RandomAccessFile raf = new RandomAccessFile(“raf.dat”, “rw”);只能是 “r”, “rw”, “rws”, or "rwd"否则参数不合法
Exception in thread “main” java.lang.IllegalArgumentException: Illegal mode “aw” must be one of “r”, “rw”, “rws”, or “rwd”
//
字符流操作
public class Test03 {
public static void main(String[] args) {
//字符缓冲输入流
BufferedReader br = null;
try {
//InputStreamReader转换流将字节流转化为字符流
br = new BufferedReader(new InputStreamReader(new FileInputStream(“note.txt”),“GBK”));
String str = null;
//字符缓冲输入流读取数据
while((str = br.readLine()) != null) {
System.out.println(str);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}
2021/5/14
课外拓展之工厂模式
工厂方法模式分为三种:
1、普通工厂模式关系图:

举例如下:(我们举一个发送邮件和短信的例子)
首先,创建二者的共同接口:
public interface Sender {
public void Send();
}
其次,创建实现类:
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println(“this is mailsender!”);
}
}
public class SmsSender implements Sender {

@Override  
public void Send() {  
    System.out.println("this is sms sender!");  
}  

}
最后,建工厂类:
public class SendFactory {

public Sender produce(String type) {  
    if ("mail".equals(type)) {  
        return new MailSender();  
    } else if ("sms".equals(type)) {  
        return new SmsSender();  
    } else {  
        System.out.println("请输入正确的类型!");  
        return null;  
    }  
}  

}
我们来测试下:
public class FactoryTest {

public static void main(String[] args) {  
    SendFactory factory = new SendFactory();  
    Sender sender = factory.produce("sms");  
    sender.Send();  
}  

}
简单工厂模式:通过工厂类来获得具体产品的实例对象,但是对象类型不正确时会报错
输出:this is sms sender!
2、多个工厂方法模式:将上述工厂类进行修改,工厂的多个方法实现具体产品实例对象
public class SendFactory {
public Sender produceMail(){
return new MailSender();
}

public Sender produceSms(){  
    return new SmsSender();  
}  

}
测试类如下:
public class FactoryTest {

public static void main(String[] args) {  
    SendFactory factory = new SendFactory();  
    Sender sender = factory.produceMail();  
    sender.Send();  
}  

}
输出:this is mailsender!
3、静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
public class SendFactory {

public static Sender produceMail(){  
    return new MailSender();  
}  
  
public static Sender produceSms(){  
    return new SmsSender();  
}  

}
public class FactoryTest {

public static void main(String[] args) {      
    Sender sender = SendFactory.produceMail();  
    sender.Send();  
}  

}
输出:this is mailsender!
总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。
4、抽象工厂模式(Abstract Factory)
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。

请看例子:
public interface Sender {
public void Send();
}
两个实现类:
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println(“this is mailsender!”);
}
}
public class SmsSender implements Sender {

@Override  
public void Send() {  
    System.out.println("this is sms sender!");  
}  

}
两个工厂类:
public class SendMailFactory implements Provider {

@Override  
public Sender produce(){  
    return new MailSender();  
}  

}
public class SendSmsFactory implements Provider{

@Override  
public Sender produce() {  
    return new SmsSender();  
}  

}
在提供一个接口:
public interface Provider {
public Sender produce();
}
测试类:
public class Test {

public static void main(String[] args) {  
    Provider provider = new SendMailFactory();  
    Sender sender = provider.produce();  
    sender.Send();  
}  

}
其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值