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();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术