JavaAPI

Scanner类

该类是文本扫描类

构造方法

//创建一个扫描输入内容的扫描器
Scanner sc = new Scanner(Sytem.in);
//扫描文本内容的扫描器
File file = new File("C:\\Users\\Administrator\\Desktop\\test.txt");
Scanner sc = new Scanner(file);

类中方法

//从键盘中读取内容
int  变量 = sc.nextInt();
byte  变量 = sc.nextByte();
short  变量 = sc.nextShort();
long  变量 = sc.nextLong();
float  变量 = sc.nextFloat();
double  变量 = sc.nextDouble();
boolean  变量 = sc.nextBoolean();
//获取单个单词(以" "为分隔符,获取到分隔符)
String 变量 = sc.next();
//获取一行内容(获取到换行符)
String 变量 = sc.nextLine();
//检测下一行是否有内容
boolean bl = sc.hasNextLine();

Object类

该类是所有类的父类,每一个Java类都直接或间接继承object类

构造方法

//语法  Object 对象名 = new Object();
Object obj = new Object();

方法

//toString方法,如果类没有重写toString方法,该方法默认形成类名@hashCode的值的十六进制形式。
//	hashCode方法,获取对的hash值,用于区分对象
obj.hashCode();
//	equals方法,默认功能比较两个对象是否相同,等同于 ==
str.equals("字符串")
//	finalize	方法,手动进行垃圾回收,(一般不需要手动调用,系统会默认回收)

String类

该类是被final修饰的类,不可被继承,该类的对象一旦被创建,就不能进行内容修改,一旦修改就是一个新的对象

作用:String类代表字符串。 Java程序中的所有字符串文字都被实现为此类的实例。

构造方法

//直接创建 String 对象名 = "值";
String str = "afauofbapfia";
//无参构造方法创建
String 对象名 = new String();
//通过有参构造方法,获取字节数组中的内容,形成字符串
byte[] bytes = {12,65,16};
String str = new String(bytes);
//获取字符数组中的内容,形成字符串
char[] chars = {'a','b','c'};
String str2 = new String(chars);
//把一个字符串包装之后形成一个新对象
String str3 = new String(str2);

字符串操作方法

//1、根据下标获取字符串中的一个字符 charAt
char c = charAt(0);
//2、获取指定字符的下标位置(从前往后,获取匹配到的第一个) indexof
int i = str.indexof('A');
//3、获取指定字符串的下标位置(从前往后,获取匹配到的第一个)indexof
int  i=str.indexOf("字符串");
//4、获取指定字符串的下标位置(从指定下标位置开始,从前往后,获取匹配到的第一个)
int  i = str.indexOf("字符串",起始下标);
//5、获取指定字符的下标位置(从后往前,获取匹配到的最后一个)
int  i= str.lastIndexOf('字符');
//6、获取指定字符串的下标位置(从后往前,获取匹配到的最后一个)
int  i = str.lastIndexOf("字符串");
//7、获取指定字符串的下标位置(从指定下标位置开始,从后往前,获取匹配到的最后一个)
int  i = str.lastIndexOf("字符串",起始下标);
//8、判断字符串是否以指定内容开始
boolean bl = str.startWith("开始内容");
//9、判断字符串是否以指定内容结尾
boolean bl = str.endWith("结束内容");
//10、截取字符串(包头不包尾)
String i = str.subString(起始下标,结束下标);
//11、替换字符
String i = str.replace('旧字符','新字符');
//12、替换字符中的子字符串
String str1 = str.replaceAll("子字符串","替换的新内容");
//13、根据指定的分隔符,分割字符串,形成字符串数组
String[] strings = str.split("分隔符");
//14、获取字符串的字符数组
char[] chars = str.toCharArray();
//15、获取字符串的字节数组形式
byte[] bytes = str.getBytes();
byte[] bytes = str.getBytes("字符集名称");
//16、比较字符串的内容是否相同
boolean b = str1.equals(str2);
//比较两个字符串变量中保存的是否为同一个对象
boolean 变量 = 对象1==对象2; (引用数据类型使用==比较地址值)
//忽略大小写,进行字符串内容比较
boolean b = str1.equalsIgnoreCase(str2);
//17、检测字符串是否符合指定的规则
boolean b= str.matchs("规则字符串");
/**正则表达式
					^ :字符串开始
					$ :字符串的结束位置
					[]:一个字符位置
					[a-zA-Z]:该位置为一个字母
					[0-9] :该位置为一个数字
					{}:指定{}之前的规则连续出现的次数
					{5} :连续出现5次
					{5,} : 最少连续出现5次
					{5,10} :最少连续出现5次,最多出现10次
*/
//18、把字符串中的大写字母转为小写字母
String str1 = str.toLowerCase();
//19、把字符串中的小写字母转为大写字母
String str1 = str.toUpperCase();
//20、去除字符串前后的空格
String str1 = str.trim();
//21、字符串拼接
String str = str1.concat(str2);
//22、把基本数据类型的值,转为字符串
String 变量 = String.valueOf(基本类型值);

String Buffer类

该类是一个可变字符串类,使用该类创建的对象,具有字符串缓冲区

String Buffer的对象创建方法

//  无参构造方法
StringBuffer stringbuffer = new StringBuffer();//默认是16个字符的缓冲区
//可以在构造时,指定缓冲区大小
StringBuffer stringbuffer = new StringBuffer(22);
//根据String字符串构建一个StringBuffer对象
String str = "fqwgqg";
StringBuffer stringbuffer1 = new StringBuffer(str);

String Buffer中的方法

//append方法,在已有的内容之后追加新的内容,不会形成新的对象,在原来的基础上进行修改
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("不是Ikun").append("不梳中分");
//insert方法,在指定下标位置插入内容(不会形成新对象,对已有对象内容进行更改)
stringbuffer.insert(2,"content");
//delete方法,删除内容(包头不包尾)(不会形成新对象,对已有对象内容进行更改)
//对象名.delete(起始下标,结束下标);
stringbuffer.delete(1,2);
//内容反转.不会形成新对象,对已有对象内容进行更改
//对象名.reverse();
stringbuffer.reverse();
//截取内容(会形成新的String对象,对已有的StringBuffer对象没有影响)
//String 变量 = 对象名.subString(起始下标,结束下标);
stringbuffer.substring(1,2);
//替换(不会形成新对象,对已有对象内容进行更改) 
//对象名.replace(起始下标,结束下标,新内容);
stringbuffer.replace(0,2,"content")
//7、获取字符串长度
//int 变量 = 对象名.length();
stringbuffer.length();
//根据StringBuffer 对象转换形成一个String对象(产生一个新的String对象,对已有的StringBuffer对象没有影响)
//String 变量  = 对象名.toString();
stringbuffer.toString();

String Builder对象的创建和功能基本与String Buffer中一致。

String Buffer和String Builder的区别

​ String Buffer线程安全,效率较低。

​ String Builder线程不安全,效率高。

包装类

什么是包装类:

​ 实现基本数据类型和引用数据类型之间进行转换的类。

包装类

​ byte -----> Byte

short -----> Short

​ int ------> Integer

​ long ------> Long

​ float -------> Float

​ double -----> Double

​ char -------> Character

​ boolean -----> Boolean

自动装箱:基本数据类型值,直接转换为对应包装类类型对象

​ 包装类 对象名 = 基本类型值;

​ 例如:😍😍

​ Integer i = 21;

自动拆箱:包装类对象,直接转换为对应的基本数据类型值

​ 基本数类型 变量名 = 包装类对象;

​ int a = new Integer("897");

把字符串转换为对应的基本数据类型

​ 基本数据类型 变量 = new 包装类对象("字符串");

​ int a = new Integer("897");

​ 或

​ 基本数据类型 变量 = 包装类对象.valueOf(“字符串”);

​ int num = Integer.valueOf("889");

Big Integer类和Big Decimal类

Math类

Math类中的方法

Math.random();
Math.ceil();
Math.floor();
Math.round();
Math.pow();
Math.max();
Math.min();
Math.abs();

Date类

Calendar类

//1.构建Calendar
Calendar cl=Clandar.getInstance();
//2.Calendar对象的方法
//2.1  set方法 给当前对象设置年月日
cl.set(2023,9,14);
//2.2  Calendar对象转为Date对象
Date date = cl.getTime();
//2.3 get方法Calendar对象获取对象里面的年月日
cl.get(Calendar.YEAR);

Simple Date Format类

该类是是日期类主要用来转换日期,将String日期文本转换成Date对象,将Date对象转换成String日期文本

//1.把String日期文本转换成Date对象
String str = "2023/01/03";
String pattern = "yy/MM/dd";
//该构造方法传入指定的格式化模板
SimpleDateFormat sf = new SimpleDateFormat("pattern");
Date date = sf.parse(str);//parse 根据SimpleDateFormat对象传入的模板来解析字符串,用一个Date对象接收

//2.把Date对象解析成String日期文本对象
Date date = new Date();
String pattern = "yy/MM/dd";
String str = sf.format(date);

集合

集合是java中提供的一种容器,可以用来存储多个数据,并且可以存储任意类型的数据!

  • 集合和数组的区别

    • 数组的长度是固定的。集合的长度是可变的。
    • 数组中存储的是同一类型的元素,可以存储基本数据类型值。
    • 集合存储的都是对象。而且对象的类型可以不一致,不能存放基本数据类型
  • 集合分为两类

    • 第一类是单列集合 collection 单列集合包含set(无序的,不允许存入重复元素。)集合和List集合(索引精确控制序列中元素,可以存入相同的元素)

      List 有序的,有一个索引,可以通过索引获取元素,可以存入相同元素

      ​ ArrayList 底层是数组,每次进行数据添加和删除,都会生成一个新数组,原数组中的内容copy到新数组中,再进行新内容的追加

      ​ 特点:查询速度快,但是添加和删除操作效率较低

      ​ LinkedList 底层是链表,查询速度慢,添加和删除效率高

      ​ Vector 底层也是数组,他线程安全,效率

      Set 无序的,不可以存入相同元素

      ​ HashSet 底层使用HashMap进行的内容存储,数据结构为哈希表形式。

      ​ LinkedHashSet 底层是哈希表和链表,会根据元素的插入顺寻进行排序

      ​ TreeSet 底层树结构,不能存入null值,且存入值时,需要存入具有转换关系的值。该集合中会对值进行升序排序。

    • 第二类是双列集合 Map

      ​ HashMap 底层 哈希表结构, 键允许存入一个null, 值允许多null.存在

      ​ LinkedHashMap 底层是链表+哈希表结构。 在HashMap的基础上记录添加的顺序。

      ​ TreeMap 底层是红黑树结构,根据键的大小进行排序,键不允许存储null.

      ​ HashTable 底层是哈希表 。 线程安全。

      ​ 与HashMap比较:

      ​ HashMap:线程不安全,效率高;

      ​ HashTable:线程安全,效率低.

集合的构建和方法

  • 没有索引的单列集合 collection

//1.构建collection对象,collection是一个接口是一个特殊的父类,用他的实现类来构建一个collection对象
Collection collection = new ArrayList<>();
//2.collection常用方法
//2.1 add方法,向collection集合中添加一个元素
collection.add("abcde");
collection.add("abcde");
collection.add("dada");
collection.add(new Date());
collection.add("上山打老虎");
Collection collection1 = new ArrayList<>();
collection1.add("12345");
collection1.add("iKun");
collection1.add("dada");
//2.2 addAll方法,向collection对象里加入批量加入元素(并入一个新的集合)
collection.addAll(collection);
//2.3删除集合中的一个元素
collection.remove("dada");
//2.4删除集合中的元素根据传入的集合
collection.removeAll(collection1);
//2.5 判断集合中是否包含某一个元素 返回值是布尔类型
boolean b = collection.contains("adcde");
//2.6 判断集合是否包含另一个集合
collection.containsAll(collection1);

//2.7遍历集合,,,构建一个迭代器对象来遍历
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
       System.out.println(iterator.next());
}
  • 带索引的单列集合 list

//1.构建collection对象,用List接收,他是collection的一个子接口,可以通过索引访问集合中的元素
List list = new ArrayList<>();
//2.collection常用方法
//2.1 add方法,向collection集合中添加一个元素
list.add(0,"郭八");
list.add(1,"张三");
//再次在第一个位置添加,会本原来的第一个位置的元素给挤下去,让原来的往后移动
list.add(1,"王五");
list.add(2,"李四");
List list1 = new ArrayList<>();
list1.add(0,"李四");
list1.add(1,"七七");

//2.2 addAll方法,向collection对象里加入批量加入元素(并入一个新的集合)
list.addAll(0,list1);
//2.3删除集合中的一个元素
list.remove("张三");
//2.4删除集合中的元素根据传入的集合
boolean b = list.removeAll(list1);
//2.5修改对应索引的内容
list.set(0,"张鹏");
//2.5 判断集合中是否包含某一个元素 返回值是布尔类型
boolean b = list.contains("adcde");
//2.6 判断集合是否包含另一个集合
list.containsAll(list1);

//2.7遍历集合,,,构建一个迭代器对象来遍历
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
       System.out.println(iterator.next());
}
//2.8加强for循环遍历集合
for (Object obj : list){
    
}
  • Set集合 HashSet

 //用hashset实现类来构建set对象
        HashSet set = new HashSet<>();
        //在set集合里添加元素
//set.addAll();
        set.add("张三");
        set.add("李四");
        //查看集合的大小
        set.size();
        //删除集合中的一个元素
        set.remove("");
        //判断集合中是否包含某一个元素 返回值是布尔类型
        set.contains("李四");
        //判断集合是否包含另一个集合
        //set.containsAll(集合名)
  • map集合

  //创建一个map对象,一般用HashMap实现类来构建map对象,双列集合一般是用键值对存放数据

        Map map = new HashMap<>();

        //在双列集合里放数据
        map.put("姓名","张三");
        map.put("性别","🚺♀");

        Map map1 = new HashMap<>();
        // 把 指定的map集合复制到此集合
        map1.putAll(map);
        //System.out.println(map1);

        //从map集合里删除一个给定键的映射
        map.remove("姓名");
        System.out.println(map);

        //修改 直接使用put覆盖原来的键值对,map中的key不能重复,一旦重复覆盖原有的值
        map.put("姓名","郭把");
        System.out.println(map);

        //查询集合中的map键值对数量
        int  i = map.size();
        System.out.println(i);
        //要获取map里面值,可以通过键来获取
        //单个获取
        Object obj= map.get("性别");
        System.out.println(obj);

        //获取集合中所有的value值
        Collection values = map.values();
        System.out.println(values);

        //获取双列集合里面的键  set集合里面不允许放入重复的元素,map的key也不允许放入重复的
        Set set = map.keySet();
        System.out.println(set);

        //遍历键所在的集合来遍历map集合里面的值,获取所有的键名和键值
        System.out.println("遍历键所在的集合来遍历map集合里面的值");
        for (Object ob:set){
            System.out.println(map.get(ob));
        }

        //调用map的entrySet()方法,把map中的键值放到set集合里
        Set set1 = map.entrySet();
        for (Object o : set1) {
            Map.Entry entry = (Map.Entry) o;
            entry.getValue();
            System.out.println(entry.getKey());
        }

泛型

泛型是可以在类或方法中预支地使用未知的类型。

使用泛型最大的好处就是可以避免类型强制转换的问题,同时也能增强程序的安全性

泛型的使用

泛型类

//把泛型定义在类上面
public class Demo02 <T>{
    T a;
    public T num(T a){
        return a;
    }
}

泛型类使用 在创建该类对象的时候使用泛型

Demo02<Integer> demo1 = new Demo02<>();
demo01.a =13;

泛型方法

public class Demo01{
	public <T> T show(T a){
        System.out.println(a);	
    }
}

File类

文件类,构造方法可以构造文件对象,用来对文件进行各种操作

构造方法

//新建一个文件对象,,通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 
File file = new File("D:\\book\\经典文件夹");
/**从父抽象路径名和子路径名字符串创建新的 File实例*/
File file1 = new File(file,"传记")

File类的功能方法

//判断文件是否存在,返回值是boolean类型
boolean b = file.exists();
//删除文件
file.delete();
//创建文件
file.createNewFile();
//创建文件夹
file.mkdir();
//获取文件名
file.getName();
//获取文件的父目录
file.getParent();
//判断文件是不是目录,是不是文件
file.isDectory();
file.isFile();
//获取文件长度
file.length();

IO流

IO流是程序和文件之间进行数据传输的技术,有字节输入输出流和字符输入输出流

向文件写入,out,writer,,从文件中读取,in,reader

字节输入流 InputStream

//字节输入流,读取文件内容
//构建一个输入流对象
InputStream inputStream = new FileInputStream("D:\\book\\帮助说明.txt");
//读取文件的内容,一个字节一个字节的读,如果返回值是-1就说明读到了文件末尾
int i = inputStream.read();
while (i != -1) {
	System.out.print((char) i);
	 i = inputStream.read();
}
byte[] bytes = new byte[1024];
//读取内容到字节s
int i = in.read(bytes);
while (i != -1) {
	for (int j = 0; j < i; j++) {
	System.out.print((char) bytes[j]);
	}
	i=in.read(bytes);
}
//关闭流
inputStream.close();

字节输出流OutputStream

//用FileOutputStream抽象类来实现流的构建,文件不存在会自动创建这个文件
OutputStream out = new FileOutputStream("D:/test.txt", true);
//向文件写入一个字符
out.write('1');
//向文件里写入数据一次写入多个字符
//写入的时候会把byte数组里面的数字转换成对应的字符写入到文件里面
byte[] bytes = {90,97,101,105};
String str = "216645198";
byte[] bytes1 = str.getBytes();
//out.write(bytes);
out.write(bytes1);
out.close();

字符输入流Reader

//创建字节输入流对象 从文件中以一个一个字符的形式冲文件中读取数据
Reader reader = new FileReader(""D:/test.txt");
//从文件里读取一个字符
reader.read();
//读取一个字符串的内容
char[] chars = new char[10];
reader.read(chars);
//返回值num,只有读到最后一个时num值为-1                               
int num = fileReader1.read(chars);
while (num!=-1){
    for (int i = 0; i < num; i++) {
         System.out.print(chars[i]);
     }
//更新num的值
num = fileReader1.read(chars);
}
//关闭流
reader.close();                               

字符输出流Writer

 //构造一个write对象,向文本里写入字符内容
 Writer writer = new FileWriter("D:/test2.txt",true);
//向文件里写入内容,v以是字符串,可以是一个字符,也可以是字符数组
//写入字符串内容
        writer.write("你好我好大家好,nini");
        //写入字节内容
        writer.write('A');
        //写入,字符数组
        char [] chars = {'a','b','c'};
        writer.write(chars);
        writer.close();

转换流,字节输入输出流转化为字符输入输出流

//1.构造一个字符输入输出流对象

//2.使用InputStreamWriter

序列化流

该流是向文件里读取或者写入对象的,把对象序列化,用对象输入输出流读取和输出

//怎么把对象序列化
//对象的类名继承  Serializable 接口
public class Book implements Serializable {
    private String name;
    private  int  id;
    ......;
    ......;
    ......;
}
  //一个字节序列可以表示一个对象,该字节序列包含对象的信息,可以把该字节序列写出到文件,相当于文件中持久保存了一个对象信息

        //创建输出流对象
        FileOutputStream out = new FileOutputStream("D:/book/book.txt",true);
        //创建book对象
        Book book = new Book("水浒传",1);
        //使用对象输出流进行对象的整体输出(序列化输出流)
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);

        objectOutputStream.writeObject(book);
        objectOutputStream.close();
  //创建字节输入流对象
        FileInputStream inputStream = new FileInputStream("D:/book/book.txt");
        //转换成对象输入流(反序列化输入流)
        ObjectInputStream stream = new ObjectInputStream(inputStream);

        //读取内容
        Object object = stream.readObject();
        Book book = (Book) object;
        System.out.println(book.getName()+book.getId());
        stream.close();
    }

线程

线程的创建

继承Thread创建

//1.创建一个类继承Thread
public class Demo01 extends Thread {
    //2.重写Thread里的run方法
    @Override
    public void run() {
        for (int i = 0; i < 11; i++) {
            System.out.println(this.getName()+" "+i);
        }
    }
}
//3.创建多线程对象
Demo01 demo01 = new Demo01();
Demo01 demo02 = new Demo01();
Demo01 demo03 = new Demo01();
//4.start开启多线程
demo01.start();
demo02.start();
demo03.start();

实现Runnable接口创建多线程

//1.创建线程类实现Runnable接口
public class RunnableDemo01 implements Runnable {
//2.重新run方法
    @Override
    public void run() {
        print();
    }
//3.创建线程类对象
RunnableDemo01 runnableDemo01 = new RunnableDemo01();
//4.通过Thread类,创建Thread对象
Thread thread1 = new Thread(runnableDemo01);
Thread thread3 = new Thread(runnableDemo01);
Thread thread2 = new Thread(runnableDemo01);
//5.开启线程
thread1.start();
thread2.start();
thread3.start();

什么是并发,什么是并行

并行就是同一时间内一块发生,需要多个cpu

并发就是在同一时间内有多个线程发生

线程中的功能方法

//1.run方法,线程功能的执行方法,如果要多线程执行,需要写run,一般写在线程类里面

//2.start方法,开启多线程,run方法的调用时通过该方法
//3.setName方法,修改线程的名字
thread.setName("售票1");
//4.getName方法,获取当前的线程名字
String name = thread.getName();
//5.sleep方法,使当前的线程进入休眠状态,传入参数为休眠的毫秒值,该方法为static方法需要通过Thread类调用
Thread.sleep(2000);
//6.setPriority方法,设置线程的优先级 优先级范围1~10
thread.setPriority(10);
//7.yield方法,线程礼让方法,你一次我一次,大家一人一次,不抢CPU
thread.yield();
//8.join方法,抢占方法,当前线程执行完毕再执行其他线程的方法
thread.join();
//9.setDaemon方法,设置守卫线程,随着其他线程的结束的结束而结束自己的线程
thread.setDaemon(true);

线程安全

多线程之间一块执行,造成数据的更新不及时,导致其他线程拿不到准确的结果,可以采用加锁的方法来解决这个问题

//1.在代码块前加上 synchronized,写一个成员变量作为钥匙,也是synchronized的参数
private obj = new Object();
synchronized(obj){
    代码
    代码
    代码
}
//2.把代码块写一个方法里面,给方法加synchronized
public synchronized void test(){
           代码块
               代码块
               代码块

}

死锁

多个线程共有多个对象锁,且出现锁中套锁现象,并且多个线程中的锁的使用顺序也是不同的。

避免死锁的方法
1.不要使用套锁形式
2.如果出现套锁形式,则多个线程中保证所有的使用顺序一致

网络编程

基于UDP编程

UDP协议是不可靠协议,,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念

客户端

 Scanner sc = new Scanner(System.in);
        //构造一个发送对象,饼指定端口号
        DatagramSocket datagramSocket = new DatagramSocket();
        while (true){
            System.out.println("请输入要发送的数据");
            String str= sc.nextLine();
            byte[] bytes = str.getBytes();
            if (str.equals("123")){
                break;
            }
            //新建一个数据报对象
            DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);

            //发送数据,以数据报的形式发送
            datagramSocket.send(datagramPacket);

            //关闭

        }
        datagramSocket.close();	

服务端

  DatagramSocket datagramSocket = new DatagramSocket(6666);
      while (true){
          //构造一个接收端对象,指定接收哪个端口的数据报
          byte[] bytes = new byte[1024];
          DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
          //接受收据报
          datagramSocket.receive(datagramPacket);
          String s = new String(bytes);
          String s1 = s.trim();
          System.out.println(datagramPacket.getAddress()+":"+s1);

      }

基于TCP编程

Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。

客户端

  Scanner sc = new Scanner(System.in);
        //创建客户端对象,创建套接字对象并指定链接的ip和端口号
        Socket socket = new Socket("127.0.0.1", 8888);
        while (true) {
            //创建套接字输出流对象,往套接字写入数据
            OutputStream outputStream = socket.getOutputStream();
            System.out.println("输入发送信息:");
            String str1 = sc.nextLine();
            outputStream.write(str1.getBytes());


            //接受信息
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            inputStream.read(bytes);
            String s = new String(bytes).trim();
            System.out.println("收到信息:"+s);

            if (str1.equals("")){
                break;
            }
        }

        socket.close();

服务端

Scanner sc = new Scanner(System.in);
        //创建服务器对象
        ServerSocket server = new ServerSocket(8888);
        //监听服务器8888端口号接收的数据包,并用套接字接受
        Socket socket = server.accept();
        while (true){
            //获取输入流,从套接字里读数据
            InputStream inputStream = socket.getInputStream();
            //接受信息的数组,存放接收的信息
            byte[] bytes = new byte[1024];
            int read = inputStream.read(bytes);
            String s = (new String(bytes)).trim();
            System.out.println("接收到信息:"+s);

            //回信息
            System.out.println("请输入回复信息");
            String s1 = sc.nextLine();
            OutputStream outputStream = socket.getOutputStream();

            outputStream.write(s1.getBytes());

            if (s1.equals("")){
                break;
            }

        }
		//关闭
        socket.close();

反射

反射机制

在代码运行时,对于任意一个类,都能够通过Java代码知道这个类的属性和方法

​ 对于任意一个对象,都可以知道他的属性和方法

这种动态获取信息,以及动态调用对象的方法的功能就是反射机制

简单理解

在使用反射的时候,可以无视修饰符的类型,调用方法和属性名

可以和properties文件联合起来,读取properties文件里对象的信息

创建反射对象的三种方式

//1.利用Class类的forName静态方法创建
Class cls1 = Class.forName("类全名");
//2.通过类全名获取
Class cls2 = Student.class;
//3.通过对象获取
Student s = new Student();
Class cls3 = s.getClass();

获取构造方法

//1.1获取所有的公用的构造方法
Constructor[] constructors = cls.getConstructors();
//1.2获取单个的公共构造方法
Constructor constructor = cls.getConstructor();
//1.3获取含参数的单个构造方法,括号写传入参数的类型
Constructor constructor1 = cls.getConstructor(int.class, String.class);
//2.1获取所有的构造方法
Class[] declaredClasses = cls.getDeclaredClasses();
//2.2根据参数类型,获取任意一个修饰符修饰的构造方法
Constructor constructor3 = cls.getDeclaredConstructor(int.class);
//3.利用获得的构造方法构造对象
Student student = (Student)constructor.newInstance();
//如果是私有属性,可以设置访问
constructor.setAccessible(true);

获取方法

//1.获取所有的public方法,包括继承的方法
 Method[] methods = cls.getMethods();
//1.2获取一个public方法
Method say = cls.getMethod("say");
//1.3获取指定参数的构造方法
Method say2=cls.getMethod("say", String.class);
//2.1获取方法名
String name=method.getName();
//2.2获取方法返回值类型
Class type = method.getReturnType();
//2.3获取修饰符
int modifiers = method.getModifiers();
//2.4获取参数个数
int parameterCount = method.getParameterCount();
//通过反射对象创建一个类
Student o = (Student) cls.getConstructor().newInstance();
//2.5执行类中的方法
say.invoke(o);
say2.invoke(o,"123");
//3.1获取所有的方法,不区分修饰符
Method[] declaredMethods = cls.getDeclaredMethods();
//3.2获取单个方法,不区分修饰符
Method show = cls.getDeclaredMethod("show");
show.setAccessible(true);
show.invoke(o);

获取属性

//构造一个反射类对象
Class cls = Class.forName("demo1.Student");
//用反射类获取构造方法,然后再用这个构造方法创建一个对象
Student student=(Student)cls.getConstructor().newInstance();
//1.获取所有的public修饰属性
Field[] fields = cls.getFields();
//1.1获取单个变量名为name的成员变量
Field name = cls.getField("name");
name.set(student,"张三");
//1.2获取属性名
 String name1 = name.getName();
//1.3获取属性类型
Class type = name.getType();
//1.4获取属性修饰符
int modifiers = name.getModifiers();
//2.1获取所有的属性名

Field[] declaredFields = cls.getDeclaredFields();
//2.5根据字符串获取指定的属性名
Field id = cls.getDeclaredField("id");
id.setAccessible(true);
id.set(student,1);

枚举

枚举类是将变量的值一一列举出来,指定变量只能复制给这些值

Stream流

Stream流是一个数据通道,它用于数据操作,进行数据的过滤,查找映射

Stream流的创建方式

//调用Collection里的Stream()方法
List<Book> list = new ArrayList<Book>();
Stream<Book> stream = list.stream();

Stream流常用方法

//1.filter方法,用于对流中的数据进行过滤
list.stream().filter(s -> s.startsWith("张"));
//2.limit方法,返回此流中的元素组成的流,截取前指定参数个数的数据
list.stream().limit(3);
//3.skip方法跳过指定参数个数的数据,返回由该流的剩余元素组成的流
list.stream().skip(3);
//4.concat方法,将两个流合并成为一个流
stream.concat(stream1,stream2);
//5.foreach方法,遍历Stream流对此流的每个元素执行操作
streamforeach();

posted @   liu星一瞬  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示