网络编程,函数式接口,Stream流,反射等基础知识
一,网络编程
1.软件结构
1,C/S结构:全称为Client/Server结构,是指客户端和服务器结构
2,B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构
2.网络通信协议
1,网络通信协议:
位于同一个网络中的计算机在进行连接和通信时需要遵守的通信规则
它对数据的传输格式、传输速率、传输步骤等做了统一的规定;
2,TCP/IP协议:
传输控制协议/因特网互联协议
3)网络通信协议的分类
*UDP协议:用户数据报协议(User Datagram Protocal)
UDP协议是无连接通信协议,在数据传输时,数据的发送端和接收端不建立逻辑联机
UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输
UDP协议不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议
UDP协议的传输:
*TCP协议:传输控制协议(Transmission Control Protocal)
TCP协议是面向连接的通信协议,传输数据之前在发送端和接收端建立逻辑连接,然后再传输数据
TCP协议提供了两台计算机之间无差错的数据传输,一般用于下载、网页浏览等
TCP协议保证数据安全的特性,
TCP传输数据需要三次握手
3.网络编程三要素
1,协议
2,IP地址:指互联网协议地址(Internet Protocal Address)
IP地址是用来给一个网络中的计算机设备做的唯一编号
3,端口号:是一个逻辑端口
*当我们使用网络软件,那么操作系统就会为这个网络软件分配一个随机的端口号
或者网络软件在打开的时候向系统要指定的端口号
*端口号是由两个字节组成,取值范围在0-65535之间
注意:1024之前的端口号我们不能使用,已经被系统分配给已知网络软件了
网络软件的端口号不能重复
二,TCP通信程序
1.概念
1,TCP通信能实现两台计算机之间的数据交互,通信的两端要严格区分为客户端(Client)与服务器
2,两端通信的步骤:
服务端程序,需要事先启动,等待客户连接
客户端主动连接服务器端,连接成功才能通信,服务器不会主动连接Client
客户端与服务器建立的连接包含字节IO流对象,C/S使用这个IO对象进行通信
3,服务器和客户端的交互
实际上客户端是没有IO流对象的,表示服务器是一个ServerSocket类,客户端是Socket类
而是使用每个客户端对象Socket中提供的IO流和客户端进行交互
服务器使用客户端的字节输入流读取客户端发送的数据
服务器使用客户端的字节输出流给客户端回写数据
2.Socket类:该类实现客户端套接字(IP:port),套接字是两台设备之间通讯的端点
1,构造方法:
Socket(String host,int port)
host:服务器主机名称/IP地址,如果host是null,则相当于指定地址为回送地址(127.)
port:端口号
2,成员方法
OutputStream getOutputStream() 返回此套接字的输出流
InputStream getInputStream() 返回此套接字的输入流
void close()关闭此套接字
3,实现步骤
创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
使用Soket对象中的方法getOutputStream()获取网络字节数据流OutputStream对象
使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
释放资源(Socket)
4,注意:
客户端和服务器进行交互,必须使用Socket中提供的网络流
当我们创建客户端对象Socket的时候,就回去请求服务器和服务器经过3次握手连接通路
这时如果服务器没有启动,那么就会抛出异常
如果服务器已启动,那么就可以进行交互了
3.ServerSocket类:该类表示服务器套接字
1,构造方法
ServerSocket(int port) 创建绑定到特定端口的服务器套接字
2,成员方法
Socket accept() 侦听并接受此套接字的连接
3,服务器实现步骤
创建服务器ServerSocket对象和系统指定的端口号
使用ServerSocket对象中的方法accept,获取到客户端的流
使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
使用网络字节输入流InputStream对象中的方法read,读取客户端输入的数据
使用Soket对象中的方法getOutputStream()获取网络字节数据流OutputStream对象
使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
释放资源
---------------------------------------------------------------------------------------------------
二,函数式接口
1.函数式接口
1,函数式接口
有且只有一个抽象方法的接口,称之为函数式接口
接口中可以包含其他的方法(默认,静态,私有)
2,@FunctionalInterface注解
可使用@FunctionalInterface注解,检查接口是否为函数式接口
2.函数式编程
1,Lambda的延迟执行
*背景:有些场景的代码执行后,结果不一定被使用,从而造成性能浪费
而Lambda表达式是延迟执行的,正好可以作为解决方案,提升性能
*Lambda的特点:延迟加载
使用Lambda表达式作为参数传递,仅仅是把参数传递到方法中,只有满足条件,才会执行函数式接口中的方法
*Lambda的使用前提:必须存在函数式接口
2)使用Lambda作为参数和返回值
3.Supplier生产型函数式接口
*抽象方法
T get(): 用于获取一个对象或值.
至于获取什么值, 怎么获取, 需要我们根据应用场景编写Lambda来实现
指定生产接口的泛型是什么类型,接口方法get()就会生产什么类型的数据
4.Consumer函数式接口: 消费型函数式接口
1,抽象方法
void accept(T t): 用于消费(使用)一个对象或值.
至于怎么消费, 需要我们根据应用场景编写Lambda来实现(输出..计算..等)
接口指定什么类型,就使用什么类型的数据
2,默认方法:
default Consumer<T> andThen(Consumer<? super T> after)
如果要有两个消费接口实现类con1和con2
con1.accept(s);
con2.accept(s);
等同于
con1.andThen(con2).accept(s) 注:谁在前谁先消费
5.Predicate函数式接口: 条件判断
抽象方法
boolean test(T t): 判断参数传递的对象.
至于怎么判断, 要判断什么, 需要我们编写Lambda表达式来实现
默认方法 (用于连接多个判断条件)
default Predicate<T> and(Predicate<? super T> other): 与
default Predicate<T> or(Predicate<? super T> other): 或
default Predicate<T> negate(): 非, 取相反结果
6.Function: 转换式函数接口
T称为前置条件, 也就是输入(input)的类型
R称为后置条件, 也就是返回结果(result)的类型
有进有出, 所以称为"函数Function"
抽象方法
R apply(T t): 将T转换为R
默认方法
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)
拼接多个Function转换
------------------------------------------------------------------------------------------------------
三,Stream流 :
一,Stream流
常用的流操作
1,获取流对象
2)Stream方法:
延迟方法:返回值仍然是stream接口自身类型的方法
*Stream filter(Predicate p): 过滤
Lambda表示需要重写Predicate<T> 参数的test(T)方法
*Stream map(Function f): 转换映射
Lambda表示需要重写Function<T,R> 参数的apply(T)方法
*Stream limit(long n): 只要前n个
只是对流中的数据进行截取,获得一个新的流
*Stream skip(long n): 不要前n个
只是对流中的数据进行截取,获得一个新的流
结束方法:返回值不再是stream接口自身类型的方法,不再支持流式编程
*long count(): 返回流中元素的个数
*void forEach(Consumer c): 遍历消费每个元素
静态方法
Stream concat(Stream s1, Stream s2):用于把两个流合并成一个新的流
3)Stream流的特点
Stream流属于管道流,只能被使用一次(每次调用方法后生成新的流),数据会转到下一个Stream中,流紧接着关闭
二,方法引用
1.引用运算符
1,::的应用实例
-定义Printable函数式接口,定义方法 void print(String str);
-在Test类中定义printString方法: private static void printString(Printable p){
p.print("Hello World");
}
-在Test类主方法调用myPrint方法, printString(s->System.out.println(s));
-使用方法引用简化lambda表达式:
printString(System.out::println) //代替 printString(s->System.out.println(s));
2,引用运算符(::)的格式
*如果Lambda要表达的函数方案已经存在与某个方法的实现中
那么则可以通过::来引用该方法作为Lambda的替代
*对象::方法
对象和方法都必须是存在的
System.out对象是已经存在的
println方法也是已经存在的
Lambda中传递的参数一定是方法引用中那个方法可以接受的类型
**println()方法参数可以是String,所以没有问题
2.通过对象名引用成员方法
*使用前提:对象名是存在的,成员方法也存在,所以必须new一个对象
3.通过类名引用静态成员方法
*类存在,静态成员方法也已经存在,可以通过类名直接引用
4.通过super引用成员方法 :super::方法
*如果存在继承关系,当Lambda中需要super调用时,也可以使用方法引用代替
*super关键字存在,一般用在类中的主方法中
5.通过this引用成员方法 :this::方法
6.类的构造器引用 : 类名称::new
7.数组的构造器引用 : 数据类型[]::new
--------------------------------------------------------------------------------------------
反射等一些常用的API:
|
|
|
|