多线程模块
进程就是运行的程序
记事本的页面设置,如果你不执行完设置,就无法再点击其他的页面,就叫做单线程
扫雷游戏,当你在游戏中,那个计时器会一直变化,不会随着你的每次点击才变,就叫多线程
1.继承Thread类实现多线程
public class MyThread01 extends Thread{
@Override
public void run() {
for (int i = 1; i <= 30; i++) {
System.out.print(i+" ");
if(i%10 == 0){
System.out.println();
}
}
}
}
public class Test01 {
public static void main(String[] args) {
MyThread01 my1 = new MyThread01();
MyThread01 my2 = new MyThread01();
my1.start();
my2.start();
}
}
2.设置和获取线程名称
| 方法 | 作用 |
|---|---|
| setName() | 赋值线程名称 |
| getName() | 获取 |
| 用super把name传给父类 | set构造方法 |
| Thread.currentThread().getName() | 是一个静态的方法,获取正在调用的线程的名称 |
public class MyThread01 extends Thread{
public MyThread01(){
}
public MyThread01(String name){
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 30; i++) {
System.out.print( getName()+":"+i+" ");
if(i%10 == 0){
System.out.println();
}
}
}
}
public class Test01 {
public static void main(String[] args) {
MyThread01 my1 = new MyThread01("高铁");
MyThread01 my2 = new MyThread01("飞机");
my1.start();
my2.start();
}
}
##3.线程优先级
public class Test02 {
public static void main(String[] args) {
MyThread01 my1 = new MyThread01("高铁");
MyThread01 my2 = new MyThread01("飞机");
MyThread01 my3 = new MyThread01("汽车");
//显示线程优先级
System.out.println("my1的线程优先级: "+my1.getPriority());
//5
System.out.println("my2的线程优先级: "+my2.getPriority()); // 5
System.out.println("my3的线程优先级: "+my3.getPriority()); //5
// 显示线程优先级的范围和默认值
System.out.println("最小值: "+Thread.MIN_PRIORITY); // 1
System.out.println("最大值: "+Thread.MAX_PRIORITY); // 10
System.out.println("默认值: "+Thread.NORM_PRIORITY);// 5
// 设置线程优先级
my1.setPriority(1);
my2.setPriority(10);
my3.setPriority(5);
// 显示线程优先级
System.out.println("my1的线程优先级: "+my1.getPriority());
System.out.println("my2的线程优先级: "+my2.getPriority());
System.out.println("my3的线程优先级: "+my3.getPriority());
my1.start();
my2.start();
my3.start();
}
}
4.线程控制
1.sleep线程停留
@Overridepublic void run()
{
for (int i = 1; i <= 10; i++) {
System.out.print( getName()+":"+i+" ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.Join等待线程死亡
public class MyJoinTest {
public static void main(String[] args) {
MyJoin my1 = new MyJoin("曹操");
MyJoin my2 = new MyJoin("孙权");
MyJoin my3 = new MyJoin("刘备");
my1.start();
// 等待my1死亡(也就是结束)
try {
my1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
my2.start();
my3.start();
}
}
3.setDaemon(true) 设置守护线程
Thread.currentThread().setName("")(这是设置主线程)当主线程运行结束时,守护线程也必须结束:当然,结束也需要一定的时间
public class MyDaemonTest {
public static void main(String[] args) {
MyDaemon my1 = new MyDaemon("关羽");
MyDaemon my2 = new MyDaemon("张飞");
// 设置主线程
Thread.currentThread().setName("刘备");
// 设置守护线程
my1.setDaemon(true);
my2.setDaemon(true);
my1.start();
my2.start();
// 主线程的方法
for (int i = 1; i <= 2; i++) {
System.out.print(Thread.currentThread().getName()+":"+i+" ");
}
}
}
5.线程的生命周期
6.使用Runnable接口实现多线程
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.print( Thread.currentThread().getName()+":"+i+" ");
if(i%10 == 0){
System.out.println();
}
}
}
}
public class MyRunnableTest {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread my1 = new Thread(my,"高铁");
Thread my2 = new Thread(my,"飞机");
my1.start();
my2.start();
}
}
7.卖票案例
public class ImpTesp implements Runnable{
private int ticknum =1;
@Override
public void run() {
while (true){
if(ticknum<30){
System.out.println("第"+Thread.currentThread().getName()+"窗口"+"卖的第"+ticknum+"张票");
ticknum++;
}
}
}
}
出现的问题
1.一张票被多个窗口卖2.出现负数票
8.通过卖票引出的线程同步
###1.同步代码块
public class ImpTesp implements Runnable{
private int ticknum =1;
private Object obj = new Object();
@Override
public void run() {
while (true){
//给下面的代码加上一把锁,当第一个对象进来时锁上,其他对象抢到线程则不会运行。只有等到第一个对象运行完,锁就会打开,之后在抢锁。
synchronized (obj)
{
if(ticknum<30){
System.out.println("第"+Thread.currentThread().getName()+"窗口"+"卖的第"+ticknum+"张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticknum++;
}
}
}
}
2.同步方法
private synchronized void Ticks(){}如果需要生成同一把锁: synchronized(this)
private synchronized static void Ticks(){}如果需要生成同一把锁:synchronized(类名称.class)
9.线程安全的类
10.Lock锁
public class MyLock implements Runnable {
private static int ticknum =1;
private Lock lock = new ReentrantLock();
//创建一个锁,需要用锁的实现类ReentrantLock
@Override
public void run() {
while (true){
try{
// 加锁
lock.lock();
Ticks();
}finally {
// 开锁
lock.unlock();
}
}
}
private static void Ticks(){
if(ticknum<30){ System.out.println("第"+Thread.currentThread().getName()+"窗口"+"卖的第"+ticknum+"张票"); try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticknum++;
}
}
}
11.生产者和消费者模式
案例
奶箱类:
public class MilkBox {
private String name;
private int count;
private boolean stats = false;
public MilkBox(String name) {
this.name = name;
}
public synchronized void getMilk() {
//如果没有牛奶,等待生成
if(!stats){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//有就拿走:
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"的牛奶被取走");
//释放等待线程 , 改变状态
stats = !stats;
notifyAll();
}
public synchronized void setMilk(int count) {
this.count = count;
//如果有牛奶,等待拿走
if(stats){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 拿走
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("送奶工将第"+this.count+"牛奶送到"+name+"里");
//释放等待线程 , 改变状态
stats = !stats;
notifyAll();
}
}
生产者和消费者类
public class Productor implements Runnable {
MilkBox milkBox;
public Productor(MilkBox milkBox) {
this.milkBox = milkBox;
}
@Override
public void run() {
for (int j = 1; j < 6; j++) {
milkBox.setMilk(j);
}
}
}
public class Customer implements Runnable {
MilkBox milkBox;
public Customer(MilkBox milkBox) {
this.milkBox = milkBox;
}
@Override
public void run() {
while (true){
milkBox.getMilk();
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
MilkBox milkBox = new MilkBox("李九红的牛奶箱");
Productor productor = new Productor(milkBox);
Customer customer = new Customer(milkBox);
Thread my1 = new Thread(productor);
Thread my2 = new Thread(customer);
my1.start();
my2.start();
}
}
网络编程模块
1.网络编程入门
1.Ip地址
####java中的使用
public class IpTest {
public static void main(String[] args) throws UnknownHostException {
// 确认主机名称的Ip地址
InetAddress address = InetAddress.getByName("GUIPENG1212");
// 获取Ip地址的主机名称
String name = address.getHostName();
System.out.println("主机名称:"+name);
// 返回Ip地址字符串
String IP = address.getHostAddress();
System.out.println("Ip地址:"+IP);
}
}
###2.端口
3.协议
2.UDP通信程序
1.发送
public class UDPSend {
public static void main(String[] args) throws IOException {
// 创建发送端
DatagramSocket ds = new DatagramSocket();
// 把数据打包
byte[] bys = "hello,udp,我来了".getBytes();
int length = bys.length;
InetAddress address = InetAddress.getByName("192.168.137.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys,length,address,port);
// 发送数据
ds.send(dp);
// 关闭发送端
ds.close();
}
}
2.接收
public class UDPRecive {
public static void main(String[] args) throws IOException {
// 创建接收端,使用指定port
DatagramSocket ds = new DatagramSocket(10086);
// 创建数据包,接收数据
byte[]bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
do{
// 接收
ds.receive(dp);
// 解析数据包
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(data);
if((data.equals("quit"))){
// 关闭接收端
ds.close();
return;
}
}while (true);
}
}
##3.UDP通讯练习
发送端
public class UDPSend {
public static void main(String[] args) throws IOException {
// 创建发送端
DatagramSocket ds = new DatagramSocket();
// 创建输入
Scanner sc = new Scanner(System.in);
String send = sc.next();
while(true){
// 把数据打包
byte[] bys = send.getBytes();
int length = bys.length;
InetAddress address = InetAddress.getByName("192.168.137.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys,length,address,port);
// 发送数据
ds.send(dp);
if(send.equals("quit")){
// 关闭发送端
ds.close();
return;
}
send = sc.next();
}
}
}
接收端
public class UDPRecive {
public static void main(String[] args) throws IOException {
// 创建接收端,使用指定port
DatagramSocket ds = new DatagramSocket(10086);
// 创建数据包,接收数据
byte[]bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
do{
// 接收
ds.receive(dp);
// 解析数据包
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(data);
if((data.equals("quit"))){
// 关闭接收端
ds.close();
return;
}
}while (true);
}
}
4.TCP通信程序
1.发数据
public class TCPSend {
public static void main(String[] args) throws IOException {
// 建立Socket对象
Socket socket = new Socket("192.168.137.1",10010);
// 创建输入流
OutputStream os = socket.getOutputStream();
os.write("hello,TCP,我来了".getBytes());
// 关闭
os.close();
}
}
2.服务器收数据
public class TCPRecive {
public static void main(String[] args) throws IOException {
// 1.创建服务端的Socket
ServerSocket sk = new ServerSocket(10010);
// 2.监听客户端连接,生成Socket对象
Socket accept = sk.accept();
// 3. 接收字节流数据
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int len;
while((len = is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
// 4. 释放
sk.close();
}
}
##5.TCP通讯练习
1.发送端获取反馈
public class TCPSend {
public static void main(String[] args) throws IOException {
// 建立Socket对象
Socket socket = new Socket("192.168.137.1",10010);
// 创建输入流
OutputStream os = socket.getOutputStream();
os.write("hello,TCP,我来了".getBytes());
// 获取服务器反馈
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
// 关闭
os.close();
}
}
public class TCPRecive {
public static void main(String[] args) throws IOException {
// 创建服务端的Socket
ServerSocket sk = new ServerSocket(10010);
// 监听客户端连接,生成Socket对象
Socket accept = sk.accept();
// 接收字节流数据
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
// 反馈给发送端
OutputStream os = accept.getOutputStream();
os.write("服务器已经接收到信息".getBytes());
// 释放
sk.close();
}
}
2.连续发送和接收消息
public class TCPSend {
public static void main(String[] args) throws IOException {
// 建立Socket对象
Socket socket = new Socket("192.168.137.1",10010);
// 创建输入流
OutputStream os = socket.getOutputStream();
Scanner sc = new Scanner(System.in);
String s;
// 循环输入
do{
s = sc.next();
os.write(s.getBytes());
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
}while (!s.equals("quit"));
// 关闭
socket.close();
}
}
public class TCPRecive {
public static void main(String[] args) throws IOException {
// 创建服务端的Socket
ServerSocket sk = new ServerSocket(10010);
// 监听客户端连接,生成Socket对象
Socket accept = sk.accept();
String s;
do{
// 接收字节流数据
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
s = new String(bytes,0,len);
System.out.println(s);
// 反馈给发送端
OutputStream os = accept.getOutputStream();
os.write("服务器已经接收到信息".getBytes());
}while (!s.equals("quit"));
// 释放
sk.close();
}
}
3.接收数据写入文本文件
只需要对服务器接收端进行处理
public class TCPRecive {
public static void main(String[] args) throws IOException {
// 创建服务端的Socket
ServerSocket sk = new ServerSocket(10010);
File file = new File("MyFile\\TCPTest.txt");
BufferedWriter bfw = new BufferedWriter(new FileWriter(file));
if(!file.exists()){
file.createNewFile();
}
// 监听客户端连接,生成Socket对象
Socket accept = sk.accept();
String s;
do{
// 接收字节流数据
InputStream is = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = is.read(bytes);
s = new String(bytes,0,len);
bfw.write(s);
bfw.newLine();
bfw.flush();
// 反馈给发送端
OutputStream os = accept.getOutputStream();
os.write("服务器已经接收到信息".getBytes());
}while (!s.equals("quit"));
// 释放
sk.close();
}
}
4.接收和发送都来自文本文件
public class TCPSend {
public static void main(String[] args) throws IOException {
// 建立Socket对象
Socket socket = new Socket("192.168.137.1",10010);
// 获取文件
BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream("myFile\\滕王阁序.txt")));
// 创建输入流
BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 获取文件的字节数组
String line;
while((line = bfr.readLine())!=null){
bfw.write(line);
bfw.newLine();
bfw.flush();
}
BufferedReader bfr1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(bfr1.readLine());
// 关闭
socket.close();
}
}
public class TCPRecive {
public static void main(String[] args) throws IOException {
// 创建服务端的Socket
ServerSocket sk = new ServerSocket(10010);
File file = new File("MyFile\\TCPTest.txt");
BufferedWriter bfw = new BufferedWriter(new FileWriter(file));
if(!file.exists()){
file.createNewFile();
}
// 监听客户端连接,生成Socket对象
Socket accept = sk.accept();
String line;
BufferedReader bfr = new BufferedReader(new InputStreamReader(accept.getInputStream()));
while((line = bfr.readLine())!=null){
bfw.write(line);
bfw.newLine();
bfw.flush();
}
// 反馈给发送端
BufferedWriter bfw1 = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bfw1.write("服务器已经接收到信息");
// 释放
sk.close();
}
}
出现的问题:
上传文件成功后没有得到服务器的反馈
原因:
虽然文件上传完毕,读取完了但是
服务器在while的地方一直在等待接下来的数据发送,这个时候发送端已经结束了发送在等待服务器的反馈。
解决:
发送一个结束字符串
获取到就结束
问题出现2:
如果传输数据中有你定义的结束数据,则导致数据传输中断
解决:
使用自有的方法shutdownOutput,完美的解决了问题。
5.多线程实现文件上传
线程类
public class SockThread implements Runnable{
Socket socket;
int count = 0 ;
BufferedReader br;
BufferedWriter bw;
public SockThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
File file = new File("myFile\\Test["+count+"].txt");
while(file.exists()){
count++;
file = new File("myFile\\Test["+count+"].txt");
}
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
} catch (IOException e) {
e.printStackTrace();
}
try {
String s;
while((s=br.readLine())!=null){
bw.write(s);
bw.newLine();
bw.flush();
}
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("服务器接收到文件,上传成功");
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务端,永不关闭
public class TCPServes {
public static void main(String[] args) throws IOException {
// 创建接收
ServerSocket ss = new ServerSocket(10010);
// 监听生成sockt
while (true) {
Socket socket = ss.accept();
new Thread(new SockThread(socket)).start(); //调用构造方法
}
}
}
Lambda表达式
1.入门
public class LambdaDemo {
public static void main(String[] args) {
// 1.调用类对象
// MyRunnable myRunnable = new MyRunnable();
// new Thread(myRunnable).start();
// 2.匿名内部类
// new Thread(new Runnable() {
// @Override
// public void run() {
// System.out.println("线程启动");
// }
// }).start();
// 3.Lambda表达式
// new Thread( () -> {
// System.out.println("线程启动");
// } ).start();
}
}
2、Lambda表达式的标准格式
3.Lambda表达式的练习
public class EatableDemo {
public static void main(String[] args) {
Eatable e = new EatableImpl(); //有一个接口Eatable,有一个实现类
UseEatable(e); //调用方法
UseEatable(() -> {
System.out.println("wdnmd!2");
});
}
public static void UseEatable(Eatable e){
e.eat();
}
}
4.抽象方法带参数无返回值
public class FlyableDemo {
public static void main(String[] args) {
Flyable f = new FlyableImpl();
FlyUse(f);
System.out.println("----------------");
FlyUse((String s)->{
System.out.println(s);
System.out.println("ssssssss");
});
}
public static void FlyUse(Flyable f){
f.fly("wdnmd!!!!");
}
}
5.带参数带返回值
public class AddDemo {
public static void main(String[] args) {
Add add = new AddImpl();
addUse(add);
System.out.println("---------------");
addUse((int a , int b)->{
return a+b;
});
}
public static void addUse(Add A){
System.out.println(A.add(10,20));
}
}
6.Lambda表达式的省略模式
7.注意事项
1.使用Lambda ,必须要有接口 , 接口里有且仅有一个方法
2.必须有上下文环绕的使用环境,才能匹配对应的接口
8.表达式和匿名内部类的区别
接口组成更新
1.概述
2.接口中的默认方法
用于更新接口时不会做太大改动
3.接口中的静态方法
4.接口中的私有方法
方法引用
##1.体验
public class Test01 {
public static void main(String[] args) {
// 省略形式的Lambda表达式
use(s-> System.out.println(s));
// 方法引用
use(System.out::println);
}
public static void use(Table t){
t.sout("爱生活");
}
}
##2.方法引用符
3.引用类方法
4.引用对象方法
5.引用类的实例方法
6.引用构造器
函数式接口
1.体验
//函数式接口的注解
@FunctionalInterface
public interface MyIt {
void sout();
}
2.函数式接口作为方法的参数
3.函数式接口作为方法的返回值
public class Comparatorss {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("wqew");
strings.add("sdasdasd");
strings.add("1");
System.out.println("排序之前"+strings);
Collections.sort(strings,comparable());
System.out.println("排序后"+strings);
}
public static Comparator<String> comparable(){
return (String s1 , String s2)->{
return s1.length()-s2.length();
};
}
}
4.常用的函数式接口
###1.Supplier (获取接口)
public class MySupplier {
public static void main(String[] args) {
String s = getString(()->"张三");
System.out.println(s);
int[] arr = {1,4,5,2,6,3};
int Max = getMax(()->{
int max = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max)max = arr[i];
}
return max;
});
System.out.println(Max);
}
public static String getString(Supplier<String> s){
return s.get();
}
public static int getMax(Supplier<Integer> it){
return it.get();
}
}
###2.Consumer (接收接口)
public class MyConsumer {
public static void main(String[] args) {
Con("你好",s-> System.out.println(s));
Cons("我刀nmd",s-> System.out.println(s),s-> System.out.println(new StringBuilder(s).reverse().toString()));
}
public static void Con(String s , Consumer<String> stringConsumer){
stringConsumer.accept(s);
}
public static void Cons(String s , Consumer<String> stringConsumer,Consumer<String> stringConsumer2){
stringConsumer.andThen(stringConsumer2).accept(s);
}
}
3.Predicate (判断接口)
public class MyPredirate {
public static void main(String[] args) {
boolean b1 = check("hellowhord",s->s.length()>7);
System.out.println(b1);
boolean b2 = check("hellowhord",s->s.length()>3,s->s.equals("hellowhord"));
System.out.println(b2);
}
public static boolean check(String s , Predicate<String> st){
return st.test(s);
}
public static boolean check(String s , Predicate<String> st1 , Predicate<String> st2){
return st1.and(st2).test(s);
}
}
4.Fuction(结果接口)
Stream流
1.体验
public class Stream01 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("张三");
strings.add("lisi");
strings.add("WANGWU ");
strings.add("张三丰");
strings.add("张张嘴");
strings.stream().filter(s>s.startsWith("张")).filter(s>s.length()>2).forEach(System.out::println); //首字母为张,长度大于2
}
}
2.Stream流的生成方式
3.Stream流的中间操作limit和skip
public class Stream02 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("张三");
strings.add("lisi");
strings.add("WANGWU ");
strings.add("张三丰");
strings.add("张张嘴");
strings.add("wdnmd");
// 只要前两个
strings.stream().limit(2).forEach(s -> System.out.println(s));
System.out.println("--------------");
// 跳过前两个
strings.stream().skip(2).forEach(System.out::println);
System.out.println("--------------");
// 跳过前两个再取两个
strings.stream().skip(2).limit(2).forEach(s-> System.out.println(s));
}
}
4. 中间流操作的concat和distinct
public class Stream03 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("张曼玉");
strings.add("林青霞");
strings.add("王祖贤");
strings.add("刘翔");
strings.add("高飞");
strings.add("米奇妙妙屋");
// 跳过四个
Stream<String> skip = strings.stream().skip(2);
// 取前两个
Stream<String> limit = strings.stream().limit(4);
//// 合并1,2
// Stream.concat(limit,skip).forEach(s -> System.out.println(s));
// System.out.println("________________");
// 合并1,2 ,并且删除重复
Stream.concat(limit,skip).distinct().forEach(s -> System.out.println(s));
}
}
5.中间流操作的sorted
public class Stream04 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("wee");
strings.add("wed");
strings.add("wefss");
strings.add("wec");
strings.add("weass");
strings.add("westtf");
// 按照自然顺序
strings.stream().sorted().forEach(s-> System.out.println(s));
System.out.println("=========================");
// 按照长度
strings.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(s -> System.out.println(s));
System.out.println("=========================");
// 先按照长度再按照自然顺序
strings.stream().sorted((s1,s2)->{
int num = s1.length()-s2.length();
int num2 = num==0 ? s1.compareTo(s2) : num;
return num2;
}).forEach(s -> System.out.println(s));
}
}
6.中间流操作的map 和 mapToInt
mapToInt的作用是 : 把本流变成Int流
map的作用 : 执行某某操作
public class Stream05 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("10");
strings.add("20");
strings.add("30");
strings.add("40");
strings.add("50");
strings.add("60");
// 转化成数字+12
strings.stream().map(s->Integer.valueOf(s)).forEach(s-> System.out.println(s+12));
// 求和
int sum = strings.stream().mapToInt(s->Integer.valueOf(s)).sum();
System.out.println("总和: "+sum);
}
}
##7.终结流的操作
8.综合
strings 中姓赵的,不要第一个
strings1 中姓名长度等于三的
public class Stream06 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("赵雷");
strings.add("赵彧");
strings.add("徐晃");
strings.add("赵金华");
strings.add("张绍忠");
strings.add("刘梅");
ArrayList<String> strings1 = new ArrayList<>();
strings1.add("张曼玉");
strings1.add("林青霞");
strings1.add("王祖贤");
strings1.add("刘翔");
strings1.add("高飞");
strings1.add("米奇妙妙屋");
Stream.concat(strings.stream().skip(1).filter(s->s.startsWith("赵"))
, strings1.stream().filter(s -> s.length()==3))
.map(Actor::new)
.forEach(p-> System.out.println(p.getName()));
}
}
9.Collector的收集方法
public class Stream07 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("赵雷,23");
strings.add("赵彧,44");
strings.add("徐晃,34");
strings.add("赵金华,12");
strings.add("张绍忠,22");
strings.add("刘梅,10");
// List
List<String> list = strings.stream().limit(4).collect(Collectors.toList());
for (String s : list) {
System.out.println(s);
}
System.out.println("-----------------");
// Set
Set<String> set = strings.stream().filter(s->s.startsWith("赵")).collect(Collectors.toSet());
for (String s : set) {
System.out.println(s);
}
System.out.println("______________________");
// Map
Map<Integer,String> map = strings.stream().filter(s-> Integer.valueOf(s.split(",")[1])>28)
.collect(Collectors.toMap(s -> Integer.valueOf(s.split(",")[1]),s->s.split(",")[0]));
Set<Integer> set1 = map.keySet();
for (Integer integer : set1) {
System.out.println(integer+" "+map.get(integer));
}
}
}
反射
1.类加载
2.类加载器
public class Class01 {
public static void main(String[] args) {
ClassLoader c = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器: "+c);
ClassLoader c1 = c.getParent();
System.out.println("返回父类加载器: "+c1);
ClassLoader c2 = c1.getParent();
System.out.println("内置类加载器:"+c2);
}
}
3.反射
##4.获取class类的对象
public class Class02 {
public static void main(String[] args) throws ClassNotFoundException {
// 调用该对象的class属性
Class<Student> c1 = Student.class;
Class<Student> c2 = Student.class;
System.out.println(c1==c2 ? "是" : "不等于");
System.out.println("______________________");
// 调用getClass
Student student = new Student("ss",12,11);
Class<? extends Student> c3 = student.getClass();
System.out.println(c1==c3 ? "是" : "不等于");
System.out.println("______________________");
// 使用静态方法
Class<?> c4 = Class.forName("MyClass.Student");
System.out.println(c1==c4 ? "是" : "不等于");
System.out.println("______________________");
}
}
5.反射获取构造方法并使用
具体为一下三部分:
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取公共默认构造方法
Constructor<?> constructor1 = c.getConstructor();
System.out.println(constructor1);
System.out.println("-----------------------");
// 根据指定的构造方法创造对象
Object sd = constructor1.newInstance();
System.out.println(sd.toString());
public class Class03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取Student的所有的公共方法
Constructor<?>[] constructor = c.getConstructors();
for (Constructor<?> con : constructor) {
System.out.println(con);
}
System.out.println("----------------------");
// 获取单独的公共默认构造方法
Constructor<?> constructor1 = c.getConstructor();
System.out.println(constructor1);
System.out.println("-----------------------");
// 返回所以方法数组
Constructor<?>[] dcons = c.getDeclaredConstructors();
for (Constructor<?> dcon : dcons) {
System.out.println(dcon);
}
System.out.println("----------------------");
// 返回单个构造方法
Constructor<?> declaredConstructor = c.getDeclaredConstructor();
System.out.println(declaredConstructor);
System.out.println("----------------------");
// 根据指定的构造方法创造对象
Object sd = constructor1.newInstance();
System.out.println(sd.toString());
}
}
6.练习1
public class Class04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取公共默认构造方法
Constructor<?> constructor1 = c.getConstructor(String.class,int.class,int.class);
System.out.println(constructor1);
System.out.println("-----------------------");
// 根据指定的构造方法创造对象
Object sd = constructor1.newInstance("好玩的反射",12,33);
System.out.println(sd);
}
}
7.练习2
使用方法类的setAccessible来进行暴力反射,值设置为true可以取消java对访问的检查,不会报错
public class Class05 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取公共默认构造方法
Constructor<?> constructor1 = c.getDeclaredConstructor(String.class);
constructor1.setAccessible(true);
// 根据指定的构造方法创造对象
Object sd = constructor1.newInstance("好玩的反射之暴力反射");
System.out.println(sd);
}
}
8.反射获取成员变量并使用
public class Class06 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取公共变量
Field[] field = c.getFields();
for (Field f : field) {
System.out.println(f);
}
System.out.println("-------------------");
// 获取所有
Field[] declaredFields = c.getDeclaredFields();
for (Field df : declaredFields) {
System.out.println(df);
}
System.out.println("-------------------");
// 开始操作
Field fd = c.getField("haha");
// 获取公共默认构造方法
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
fd.set(obj,123);
// 根据指定的构造方法创造对象
System.out.println(obj);
}
}
9.练习3
由于name是私有变量,所以说,对Field进行 fd1.setAccessible(true); 设置,取消访问检测
public class Class07 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
// 先获取class对象:Student
Class<?> c = Class.forName("MyClass.Student");
// 获取公共变量
Field[] field = c.getFields();
for (Field f : field) {
System.out.println(f);
}
System.out.println("-------------------");
// 获取所有
Field[] declaredFields = c.getDeclaredFields();
for (Field df : declaredFields) {
System.out.println(df);
}
System.out.println("-------------------");
// 开始操作
Field fd = c.getField("haha");
Field fd1 = c.getDeclaredField("name");
Field fd2 = c.getDeclaredField("age");
// 获取公共默认构造方法
Constructor<?> con = c.getConstructor();
fd1.setAccessible(true);
Object obj = con.newInstance();
fd.set(obj,123);
fd1.set(obj,"好玩啊");
fd2.set(obj,2222);
// 根据指定的构造方法创造对象
System.out.println(obj);
}
}
10.反射获取成员方法并使用
public class Class08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<?> c = Class.forName("MyClass.Student");
// 太多了不展示了
Method[] methods = c.getMethods();
Method[] declaredMethods = c.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("--------------------");
// begin
Method method1 = c.getMethod("method1");
// 构造对象
Constructor<?> constructor = c.getConstructor();
Object obj = constructor.newInstance();
method1.invoke(obj);
}
}
11.练习4
public class Class09 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<?> c = Class.forName("MyClass.Student");
// begin
Method method1 = c.getMethod("method1");
Method method02 = c.getMethod("method02", String.class, int.class);
// 构造对象
Constructor<?> constructor = c.getConstructor();
Object obj = constructor.newInstance();
method1.invoke(obj);
Object ooo = method02.invoke(obj,"hahah倒霉蛋", 123);
System.out.println(ooo);
}
}
12.超越泛型检测
public class Class10 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ArrayList<Integer> lists = new ArrayList<>();
lists.add(12);
Class<? extends ArrayList> aClass = lists.getClass();
Method add = aClass.getMethod("add", Object.class);
add.invoke(lists,"sds");
add.invoke(lists,23);
add.invoke(lists,3.333);
System.out.println(lists);
}
}
##13.运行配置文件的指定内容
从文件中获取对象的地址和对象的方法名 , 使用IO流和Properties结合的方法
public class Class11 {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 从文件中读取Student对象地址
FileReader fr = new FileReader("myFile\\Class.txt");
Properties p1 = new Properties();
p1.load(fr);
String className = p1.getProperty("ClassName");
String methodName = p1.getProperty("MethodName");
// 从地址创建对象
Class<?> c = Class.forName(className);
// 获取方法
Method method = c.getMethod(methodName);
// 获取构造方法
Constructor<?> constructor = c.getConstructor();
// 构造对象
Object o = constructor.newInstance();
method.invoke(o);
}
}
模块化
1.基本使用
JAVA类运行时,报错“Error occurred during initialization of boot layer”
网上查原因是由于JDK9及以上版本引入了模块,所以在default package建立一个单独运行的类,就无法通过编辑。需要先删除module-info.java,删除之后,再运行就可以了。
————————————————
module Myone {
exports Mod;
}