UDP、TCP、Lambda表达式、接口组成更新、方法引用、函数式接口

UDP通信原理:UDP协议是一种不可靠的网络协议,它在通信的两端各简历一个Socket对象,但是这两个Socket只是发送,接收数据的对象

基于UDP协议的通信双方,没有所谓的客户端和服务器概念

Java提供DatagramSocket类最为基于UDP协议的Socket

UDP发送数据

发送数据的步骤

1.创建发送端的Socket对象(DatagramSocket)

        DatagramSocket()

2.创建数据,并把数据打包

        DatagramSocket(byte[] buf, int length,InetAddress address,int port)

3.调用DatagramSocket对象的方法发送数据

        void send(DatagramPacket p)

4.关闭发送端

        void close()

public class Demo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        byte[] bys = "helloworld".getBytes();
//        int length = bys.length;
//        InetAddress m = Inet4Address.getByName("m");
//        int port = 10086;
//        DatagramPacket dp = new DatagramPacket(bys,length,m,port);
        DatagramPacket dp = new DatagramPacket(bys,bys.length,Inet4Address.getByName("m"),10086);
        //发送数据报包
        ds.send(dp);
        ds.close();
    }
}

UDP接收数据

接收数据的步骤

1.创建接收端的Socket对象(DatagramSocket)

        DatagramSocket()

2.创建一个数据包,用于接收数据

        DatagramPacket​(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度为 length数据包

3.调用DatagramSocket对象的方法接收数据

        void receive​(DatagramPacket p) 从此套接字接收数据报包

4.解析数据包,并把数据在控制台显示

        byte[] getData​() 返回数据缓冲区。

        int getLength​() 返回要发送的数据的长度或接收到的数据的长度。

5.关闭接收端

        void close();

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(10086);
        //DatagramPacket​(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度为 length数据包。
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys,bys.length);
        //void receive​(DatagramPacket p) 从此套接字接收数据报包。
        ds.receive(dp);
        //byte[] getData​() 返回数据缓冲区。
//        byte[] data = dp.getData();
        //int getLength​() 返回要发送的数据的长度或接收到的数据的长度。
//        int len  = dp.getLength();
//        String dataString = new String(data,0,len);
//        System.out.println(dataString);
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        ds.close();
    }
}

UDP通信程序练习

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        while (true){
            DatagramSocket ds = new DatagramSocket(10086);
            //DatagramPacket​(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度为 length数据包。
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys,bys.length);
            //void receive​(DatagramPacket p) 从此套接字接收数据报包。
            ds.receive(dp);
            System.out.println(new String(dp.getData(),0,dp.getLength()));
            ds.close();
        }


    }
}
public class Demo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();
        //自己封装键盘录入数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = br.readLine())!=null){
            if ("886".equals(line)){
                break;
            }
            byte[] bys = line.getBytes();
            DatagramPacket dp = new DatagramPacket(bys,bys.length,Inet4Address.getByName("m"),10086);
            //发送数据报包
            ds.send(dp);
        }
        ds.close();
    }
}

TCP通信原理

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信

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

Java位客户端提供了Socket类,位服务器端提供了ServerSocket类

TCP发送数据

1.创建客户端的Socket对象(Socket)

       Socket​(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。

       Socket​(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。

2.获取输出流,写数据

        OutputStream getOutputStream​() 返回此套接字的输出流。

3.释放资源

        void close();

    public static void main(String[] args) throws IOException {
        // Socket​(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。
//        Socket s = new Socket(Inet4Address.getByName("m"),10086);
        //Socket​(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。
        Socket s = new Socket("m",10086);
        //获取输出流,写数据
        //OutputStream getOutputStream​() 返回此套接字的输出流。
        OutputStream os  = s.getOutputStream();
        os.write("hello".getBytes());
        s.close();
    }

TCP接收数据

1.创建服务器端的Socket对象(ServerSocket)

        ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。

2.监听客户端连接,返回一个Socket对象

        Socket accept​() 侦听要连接到此套接字并接受它。

3.获取输入流,读数据,并把数据显示在控制台

        InputStream getInputStream​() 返回此套接字的输入流。

4.释放资源

        void close()

   public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        //Socket accept​() 侦听要连接到此套接字并接受它。
        Socket s = ss.accept();
        //获取输入流,读数据,并把数据显示在控制台
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len;
        while ((len = is.read(bys))!=-1){
            String data = new String(bys,0,len);
            System.out.println(data);
        }
        s.close();
        ss.close();
    }

TCP通信程序练习

    public static void main(String[] args) throws IOException {
        // Socket​(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。
//        Socket s = new Socket(Inet4Address.getByName("m"),10086);
        //Socket​(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。
        Socket s = new Socket("m",10086);
        //获取输出流,写数据
        //OutputStream getOutputStream​() 返回此套接字的输出流。
        OutputStream os  = s.getOutputStream();
        os.write("hello".getBytes());
        //接收服务器反馈
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys,0,len);
        System.out.println("客户端:"+data);
//        int len;
//        while ((len = is.read(bys))!=-1){
//            String data = new  String(bys,0,len);
//            System.out.println("客户端:"+data);
//        }
        s.close();
        os.close();
        is.close();
    }
    public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        //Socket accept​() 侦听要连接到此套接字并接受它。
        Socket s = ss.accept();
        //获取输入流,读数据,并把数据显示在控制台
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys,0,len);
        System.out.println("服务器:"+data);
//        int len;
//        while ((len = is.read(bys))!=-1){
//            String data = new String(bys,0,len);
//            System.out.println("服务器:"+data);
//        }
        //给出反馈
        OutputStream os = s.getOutputStream();
        os.write("收到".getBytes());

        s.close();
        ss.close();
        os.close();
    }

数据键盘录入+接收生成文本文件练习

public class Demo {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("192.168.31.77",10086);
        //获取输出流,写数据
        //OutputStream getOutputStream​() 返回此套接字的输出流。
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line = br.readLine())!=null){
            if ("886".equals(line)){
                break;
            }
            bw.write(line);
            bw.newLine();
            bw.flush();
            //接收服务器反馈
            InputStream is = s.getInputStream();
            byte[] bys = new byte[1024];
            int len = is.read(bys);
            String data = new String(bys,0,len);
            System.out.println("客户端:"+data);
        }
        s.close();
    }
}
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        //Socket accept​() 侦听要连接到此套接字并接受它。
        Socket s = ss.accept();
       //获取输入流,读数据,并把数据显示在控制台
//        InputStream is = s.getInputStream();
//        InputStreamReader isr = new InputStreamReader(is);
//        BufferedReader br = new BufferedReader(isr);
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("untitled1\\copy.txt"));
        String line;
        while((line = br.readLine())!=null){
            System.out.println("服务器:"+line);
            bw.write(line);
            bw.newLine();
            bw.flush();
            //给出反馈
            OutputStream os = s.getOutputStream();
            os.write("收到".getBytes());
        }
        ss.close();
        bw.close();
    }
}

数据来自于文本文件,接收到的数据写入文本文件

public class Demo {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("192.168.31.77",10086);
        //封装文本文件的数据
        BufferedReader br = new BufferedReader(new FileReader("untitled1\\osw.txt"));
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line = br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
            //接收服务器反馈
            InputStream is = s.getInputStream();
            byte[] bys = new byte[1024];
            int len = is.read(bys);
            String data = new String(bys,0,len);
            System.out.println("客户端:"+data);
        }
        s.close();
    }
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        //Socket accept​() 侦听要连接到此套接字并接受它。
        Socket s = ss.accept();
       //获取输入流,读数据,并把数据显示在控制台
//        InputStream is = s.getInputStream();
//        InputStreamReader isr = new InputStreamReader(is);
//        BufferedReader br = new BufferedReader(isr);
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("untitled1\\copy.txt"));
        String line;
        while((line = br.readLine())!=null){
            System.out.println("服务器:"+line);
            bw.write(line);
            bw.newLine();
            bw.flush();
            //给出反馈
            OutputStream os = s.getOutputStream();
            os.write("收到".getBytes());
        }
        ss.close();
        bw.close();
    }
}

数据来自于文本文件,接收到的数据写入文本文件+给出反馈

public class Demo {
    public static void main(String[] args) throws IOException {
        Socket s = new Socket("192.168.31.77",10086);
        //封装文本文件的数据
        BufferedReader br = new BufferedReader(new FileReader("untitled1\\osw.txt"));
        //封装输出流对象
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while ((line = br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        //自定义结束标识
//        bw.write("886");
//        bw.newLine();
//        bw.flush();
        //void shutdownOutput​() 禁用此套接字的输出流。(输出结束)
        s.shutdownOutput();

        //接收服务器反馈
        BufferedReader brus = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String data = brus.readLine();
        System.out.println("服务器的反馈:"+data);
        s.close();
    }
}
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        //Socket accept​() 侦听要连接到此套接字并接受它。
        Socket s = ss.accept();
       //获取输入流,读数据,并把数据显示在控制台
        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("untitled1\\copy.txt"));
        String line;
        while((line = br.readLine())!=null){
            if ("886".equals(line)){
                break;
            }
            System.out.println("服务器:"+line);
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        //给出反馈
        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bwServer.write("上传成功");
        bwServer.newLine();
        bwServer.flush();
        ss.close();
        bw.close();
    }
}

出现程序一直等待的问题,(原因是读数据的方法是阻塞式的)

解决办法:自定义结束标记;使用void shutdownOutput​() 禁用此套接字的输出流。(输出结束)方法

多线程实现文件上传练习(客户端与上一练习相同)

public class ServerThread implements Runnable {
    private Socket s;
    public ServerThread(Socket s) {
        this.s=s;
    }
    @Override
    public void run() {
        try {
            //BufferedWriter bw = new BufferedWriter(new FileWriter("untitled1\\copy.txt"));
            //解决名称冲突问题
            int count = 0;
            File file = new File("untitled1\\copy["+count+"]txt");
            while (file.exists()){
                count++;
                file = new File("untitled1\\copy["+count+"]txt");
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

            String line;
            while ((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();
                bw.flush();
                System.out.println("服务器:"+line);
            }
            //给出反馈
            BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("上传成功");
            bwServer.newLine();
            bwServer.flush();

            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //ServerSocket​(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);
        while (true){
            //Socket accept​() 侦听要连接到此套接字并接受它。
            Socket s = ss.accept();
            //为每一个客户端开启一个线程
            new Thread(new  ServerThread(s)).start();
        }
    }
}

Lambda表达式

体验lambda表达式

public class LambdaDemo {
    public static void main(String[] args) {
        //匿名内部类改写多线程
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("多线程");
//            }
//        }).start();
        // Lambda表达式的方式改进
        new Thread(()->{
            System.out.println("多线程");
        }).start();
    }
}

组成Lambda表达式的三要素:形式参数,箭头,代码块

Lambda表达式格式

格式:(形式参数)—>{代码块}

形式参数:如果有多个参数,参数之间用逗号隔开:如果没有参数,留空即可

->:由应文中画线和大于符号组成,固定写法,代表指向动作

代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

Lambda表达式练习

Lambda表达式的使用前提

        有一个接口

        接口中有且仅有一个抽象方法

Lanbda表达式的省略模式

省略规则:

        参数类型可以省略,但是有多个参数的情况下,不能只省略一个

        如果参数有且仅有一个,那么小括号可以省略

        如果代码块的语句只有一条,可以省略大括号和分号,甚至是return

注意事项:

        使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法

        必须有上下文环境,才能推导出Lambda对应的接口

                根据局部变量的赋值得知Lambda对应的接口:Runnable r =()-> System.out.println("Lambda表达式");

                根据调用方法的参数得知Lambda对应的接口:new Thread(()->System.out.println("Lambda")).start();

        Runnable r =()-> System.out.println("Lambda表达式");
        new Thread(r).start();
        new Thread(()->System.out.println("Lambda")).start();

Lambda表达式和匿名内部类的区别

所需类型不同

        匿名内部类:可以是接口,也可以是抽象类,还可以是具体类

        Lambda表达式:只能是接口

使用限制不同

        如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类

        如果接口中多余一个抽象方法,只能使用匿名内部类,而不能使用:Lambda表达式

实现原理不同

        匿名内部类:编译之后,产生一个单独的.class字节码文件

        Lambda表达式:编译之后,没有一个单独的.class字节码文件,对应的字节码会在运行的时候自动生成

接口组成更新

接口组成更新概述

接口的组成

        常量:public static final

        抽象方法:public abstract

        默认方法(Java8)

        静态方法(Java8)

        私有方法(Java9)

接口中默认方法

接口中默认方法的定义格式:

        格式:public default 返回值类型 方法名(参数类型){ }

        范例:public default void show3(){  }

接口中和默认方法的注意事项:

        默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字

        public可以省略,default不能省略

接口中的静态方法

接口中静态方法的定义格式:

        格式:public static 返回值类型 方法名(参数列表){  }

        范例:public static void show(){  }

接口中静态方法的注意事项:

        静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

        public 可以省略,static不能省略

接口中的私有方法

接口中私有方法的定义格式:

        格式1:private 返回值类名 方法名(参数列表){  }

         范例1:private void show() { }

        格式2:private static 返回值类型 方法名(参数列表){  }

        范例2:private static void method(){ }(静态方法只能调用静态方法)

接口中私有方法的注意事项:

        默认方法可以调用私有方法的静态方法和非静态方法

        静态方法只能调用私有的静态方法

方法引用

    public static void main(String[] args) {
        useInter(s->{
            System.out.println(s);
        });
        //方法引用符::
        useInter(System.out::println);
        //可推导的就是可省略的
    }

方法引用符

      ::  该符号为引用运算符,而它所在的表达式被称为方法引用

推到与省略

        如果使用Lambda,根据“可推导就可省略”原则,无需指定参数类型,也无需指定的重载形式,它们都将自动被推导

        如果使用方法引用,也是同样可以根据上下文进行推导

        方法引用是Lambda的孪生兄弟

引用类方法(引用类的静态方法)

        格式:类名::静态方法

        范例:Integer::parseInt

                Interger类的方法:public static int parseInt(String)转换为int类型数据

   public static void main(String[] args) {
        useConverter(s-> Integer.parseInt(s)
        );
        useConverter(Integer::parseInt);
    }

    private static void useConverter(Converter c) {
        int cn = c.convert("9999");
        System.out.println(cn);
    }

Lambda表达式被类方法替代的时候,他的形式参数全部传递给静态方法作为参数

引用对象的实例方法

格式:对象::成员方法

范例:"HelloWorld"::toUpperCase

        String类中的方法:public String toUpperCase()将此String所有字符转换成大写

public class PrintString {
    public void printUpper(String s){
        System.out.println(s.toUpperCase());
    }
}


public interface Printer {
    void PrintUpperCase(String s);
}

public class PrinterDEmo {
    public static void main(String[] args) {
//        usePrinter((String s)->{
//            System.out.println(s.toUpperCase());
//        });
        //引用对象实例方法
        PrintString p = new PrintString();
        usePrinter(p::printUpper);
    }

    private static void usePrinter(Printer p) {
        p.PrintUpperCase("HelloWorld");
    }
}

Lambda表达式被对象的实例方法替代的时候,它的形参全部传递给该方法作为参数

引用类的实例方法

格式:类名::成员方法

范例:String::substring

        String类中的方法:public String substring(int beginIndes,int endIndex)

        从beginIndex开始到endIndex结束,截取字符串。返回一个子串,字串的长度为endIndex-beginIndex

public interface MyString {
     String mySubString(String s ,int x ,int y);
}

public class MyStringDemo {
    public static void main(String[] args) {
//        useMyString((s,x,y)->{
//           return s.substring(x,y);
//        });
        useMyString((s,x,y)->s.substring(x,y));

        //引用类的实例方法
        useMyString(String::substring);
    }
    private static void useMyString(MyString my){
        String s = my.mySubString("HelloWorld", 2, 5);
        System.out.println(s);
    }
}

Lambda表达式被类的实例方法代替的时候,第一个参数作为调用者,后面的参数全部传递给该方法作为参数

引用构造器(引用构造方法)

        格式:类名::new

        范例:Student::new

public interface StudentBuilder {
    Student build(String name,int age);
}

public class StudentDemo {
    public static void main(String[] args) {
//        useStudentBuilder((name,age)->{
//           return new Student(name,age);
//        });
        useStudentBuilder(((name, age) -> new Student(name,age)));
        //引用构造器
        useStudentBuilder(Student::new);
    }

    private static void useStudentBuilder(StudentBuilder s) {
        Student sm = s.build("xiaohuang", 30);
        System.out.println(sm.getName()+","+sm.getAge());
    }

}

Lambda表达式被构造器替代时,它的形参全部传递给构造器作为参数

函数式接口(Lambda表达式适用):有且仅有一个抽象方法的接口

@FunctionalInterface
public interface MyInterface {
    void show();
}

public class MyInterfaceDemo {
    public static void main(String[] args) {
        MyInterface my = ()-> System.out.println("函数式接口");
        my.show();
    }
}

@FunctionalInterface        放在接口定义的上方,如果接口是函数式接口,编译通过,如果不是,编译失败

注意:自己在定义函数式接口时,@FunctionalInterface是可选的,不写这个注解,只要保证满足函数式接口的定义条件,一样时函数式接口,建议加上该注解。

函数式接口作为方法的参数

如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递

        startThread(()->System.out.println(Thrasd.currentThread().getName()+"线程启动"));

函数式接口作为方法的返回值

public class MyInterfaceDemo {
    public static void main(String[] args) {
        ArrayList<String> ar = new ArrayList<String>();

        ar.add("bb");
        ar.add("ddddd");
        ar.add("aaa");
        ar.add("cccc");
        System.out.println(ar);
        Collections.sort(ar,getComparator());
        System.out.println(ar);

    }
    private static Comparator<String> getComparator(){
        //匿名内部类
//       Comparator<String> cp = new Comparator<String>() {
//           @Override
//           public int compare(String o1, String o2) {
//               return o1.length()-o2.length();
//           }
//       };
//       return cp;


//        return new Comparator<String>() {
//           @Override
//           public int compare(String o1, String o2) {
//               return o1.length()-o2.length();
//           }
//       };

        return (s1,s2)-> s1.length()-s2.length();
    }
}

如果方法的返回值是一个函数式接口,我们可以使用Lambda表达式作为返回结果

常用的函数式接口

Supplier接口

Supplier<T>:包含一个无参的方法

        T get();  获得结果

        该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据

        Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中get方法就会生产什么类型的数据供我们使用

    public static void main(String[] args) {
        String s = getString(() -> "xiaobai");

        System.out.println(s);
    }
    private static String getString(Supplier<String> sup){
        return sup.get();
    }

Consumer接口

Consumer<T>:包含两个方法

        void accept(T t): 对给定的参数执行此操作

        default Consumer<T>andThen(Consumer after):返回一个组合的Consumer,一次执行此操作,然后执行after操作

        Consumer<T>接口也被称为消费型接口,他消费的数据的数据类型由泛型指定

    public static void main(String[] args) {
        operatorString("xiaohuang",(String s )->{
            System.out.println(s);
        });
        operatorString("xiaolv",s-> System.out.println(s));
        operatorString("xiaolan",System.out::println);
        operatorString("xiaohei",s->
            System.out.println(new StringBuilder(s).reverse().toString()));
        operatorString("xiaofen",s-> System.out.println(s),s -> System.out.println(new StringBuilder(s).reverse().toString()));
    }
    //定义一个方法,用不同的方式消费同一个字符串数据两次
    private static void operatorString(String name, Consumer<String> con1,Consumer<String> con2){
//        con1.accept(name);
//        con2.accept(name);
        con1.andThen(con2).accept(name);
    }


    private static void operatorString(String name, Consumer<String> con){
        con.accept(name);
    }

练习

    public static void main(String[] args) {
        String[] sa = {"xiaohong,12","xiaocheng,15","xiaohuang,18"};
        printInfo(sa,(String s)->{
            String name = s.split(",")[0];
            System.out.print("姓名"+name);
        },(String s)->{
            int age = Integer.parseInt(s.split(",")[1]);
            System.out.println(",年龄"+age);
        });
    }
    //定义一个方法,用不同的方式消费同一个字符串数据两次
    private static void printInfo(String[] sa, Consumer<String> con1,Consumer<String> con2){
        for (String s : sa){
            con1.andThen(con2).accept(s);
        }
    }

Predicate接口

Predicate<T>:常用的四个方法

        boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值

        default Predicate<T> negate():返回一个逻辑地否定,对应逻辑非

        default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与

        default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或

Predicate<T>接口通常用于判断参数是否满足指定的条件

    public static void main(String[] args) {
        boolean b = chechString("hellojava", s -> s.length() > 8);
        System.out.println(b);
        boolean b1 = checkString("helloworld", s -> s.length() > 8, s -> s.length() < 16);
        System.out.println(b1);
    }
    private static boolean chechString(String s , Predicate<String> p){
        return p.negate().test(s);
    }
    private static boolean checkString(String s, Predicate<String> p1, Predicate<String> p2){
//        return p1.test(s)&&p2.test(s);
        return p1.and(p2).test(s);
    }

筛选练习

    public static void main(String[] args) {
        String[] ss = {"xiaohong,12","xiaocheng,15","xiaohuang,18","xiaolv,17"};
        checkString(ss, s -> s.split(",")[0].length() > 8, s -> Integer.parseInt(s.split(",")[1]) > 16);

    }
    private static void checkString(String[] ss, Predicate<String> p1, Predicate<String> p2){
//        return p1.test(s)&&p2.test(s);
        boolean test = false;
        for (String s : ss) {
             test = p1.and(p2).test(s);
            if (test){
                System.out.println(s);
            }
        }
    }

Function接口

Function<T,R>:常用的两个方法

        R apply(T t):将此函数应用于给定的参数

        default<T> Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果

        Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

    public static void main(String[] args) {
        convert("555",s->Integer.parseInt(s),s->String.valueOf(s+111));
    }
    private static void convert(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){
//        String ss = fun2.apply(fun1.apply(s));
       String ss = fun1.andThen(fun2).apply(s);
        System.out.println(ss);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值