1 网络编程
-
计算机网络:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
-
IP互联网协议,TCP传输控制协议
-
InetAddress接口:IP地址类,派生Inet4/6Address
-
UDP传输:
-
UDP(封装数据而成数据包,包括目的地址,端口,数据信息)传输
-
DatagramSocket:封装了udp传输协议的socket对象;DatagramPacket:对数据信息的包装
-
UDP的发送端:指明本端端口号,如果未指定端口,系统自动分配一个未使用的端口;构建信息并将数据封装成了数据包;用socket服务的send方法将数据包发送出去;关闭资源
DatagramSocket ds = new DatagramSocket(8888); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("10.1.31.127"),10000);
-
UDP的接收端:必须要明确一个(接收)端口;定义数据包存储接收到数据;用socket服务的接收方法receive将收到的数据存储到数据包中;通过数据包的方法(getAdress(),getPort()等)获取数据包中的具体数据内容(ip、端口、数据);关闭资源
-
-
TCP传输:
-
传输数据的通道为流(socket流)
-
建立tcp的socket服务;Socket s = new Socket("ip",8080);
-
明确具体的地址和端口(对象创建时已经可以对指定ip和端口进行连接(三次握手))
-
通过getInputStream和getOutputStream获取socket流中的读取流和写入流;OutputStream out = s.getOutputStream();out.write(str);关闭资源; s.close();
-
创建服务端socket服务,并监听一个端口; ServerSocket ss = new ServerSocket(8080);
-
通过accept方法获取连接客户端对象;Socket s = ss.accept();
-
通过获取到的socket对象中的socket流和具体的客户端进行通讯;InputStream in = s.getInputStream();
-
关闭资源。先关客户端,再关服务端;s.close(); ss.close();
-
记录客户端信息;加入多线程:用List保存每个Socket,遍历List并操作
-
网络通信应用框架:MINA
-
-
TCP/IP概念模型:4层-7层(越下越底层)及相关协议簇
-
应用层:
-
应用层:TFPT,HTTP,SNMP,FTP,SMTP,DNS,Telnet
-
表示层
-
会话层
-
-
传输层:TCP,UDP
-
网络层:IP,ICMP,RIO,OSPF,BCP,IGMP
-
链路层:
-
数据链路层
-
物理层:ISO02110,...
-
-
2 Annotation注解接口
3 函数式接口与Lambda表达式
3.1 函数式接口
-
只包含一个抽象方法的接口;可以包含任意个非抽象方法;函数式接口用注解@FunctionalInterface标注;隐式通过Lambda表达式创建接口对象
-
OOF:面向函数编程,java扩展OOP,位于java.util.function下;所有用匿名类实现的,都可改写为Lambda
-
内置4大核心接口:
-
Consumer< T>:消费型接口:接收参数,但无返回
-
void accept(T t)
-
-
Supplier< T>:供给型接口:无参数接收,有返回(Bean的getter()类似,这可以方法引用)
-
T get()
-
-
Function<T, R>:函数型接口:接收T类型对象,返回R类型对象
-
R apply(T t)
-
-
Predicate< T>:断言型接口:传入T类型参数,返回Boolean
-
boolean test(T t)
-
-
-
其他接口介绍:
接口 方法:包括参数类型与返回类型 用途 BiFunction<T,U,R> R apply(T,U) 操作两个不同类型数据,返回另一类型数据 UnaryOperator<T> T apply(T) 对某类型进行一元运算并返回 BinaryOperator<T> T apply(T,T) 对某类型进行二元运算并返回 BiConsumer<T,U> void accept(T,U) 操作两种数据类型,无返回 BiPredicate<T,U> boolean test(T,U) ToIntFunction<T> ToLongFunction<T> ToDoubleFunction<T> 接收T,计算返回int,long,double IntFuntion<R> LongFunction<R> DoubleFunction<R> 接收int,long,double参数,返回R
3.2 Lambda表达式
-
速度更快,代码更少,便于并行,减少空指针异常
-
Lambda表达式:一段可传递(像传递数据一样)的代码,一种匿名函数;需要函数式接口的支持
-
->:操作符,左侧为参数列表,对应接口的抽象方法的参数;右侧为需要执行的功能,对应抽象方法的实现体;参数类型由JVM根据上下文进行类型推断;创建接口对象;本质为接口的实例
-
无参数,无返回值:() -> System.out.println("");
-
一个参数:(int x) -> System.out.println(x);小括号可省略,返回类型可省略
-
两个及以上参数:(x,y) -> {语句};当只有一条语句时,{}可省略
-
-
Lambda表达式:() -> {}
// 原来匿名线程写法 new Thread(new Runnable() { @Override public void run() { doSomeThing...; } }).start(); // Lambda表达式写法 new Thread( () -> {doSomething...}).start(); // run()方法没有参数 // 1 原始写法 Comparator<Integer> comparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); // 核心功能 } }; System.out.println(comparator.compare(1, 2)); // 2 使用Lambda表达式 comparator = (o1, o2) -> Integer.compare(o1, o2); // 参数o1,o2的类型自动推断;可明确写出;Integer可省;当只有一条语句时,{}和return可省 comparator = (o1, o2) -> {System.out,println(o1);return compare(o1, o2);} // 当方法体有多条语句时 System.out.println(comparator.compare(1, 2)); // 常见的类型推断: // List<String> list = new ArrayList<>(); // String[] arrays = {"aaa", "bbb", "ccc"}; // 但String[] arrays2;arrays2 = {"aaa", "bbb", "ccc"};这种不能推断出类型 // 3 使用方法引用 comparator = Integer :: compare; System.out.println(comparator.compare(1, 2)); public static List<String> filterString(List<String> list, Predicate<String> predicate) { List<String> filterList = new ArrayList<>(); for (String string: list) { if (predicate.test(string)) { filterList.add(string); } } return filterList; } // 原来的调用 List<String> list = Arrays.asList("周一", "周二", "星期四"); filterString(list, new Predicate<String>() { @Override public boolean test(String s) { return s.contains("周"); // 任意的自定义实现 } }); // lambda filterString(list, string -> string.contains("周"));
3.3 方法引用
-
Lambda的深层次表示:当要传递给Lambda体的操作已经有实现的方法时,可引用该方法;这要求原操作与引用方法的参数和返回类型一致;通俗讲,即想要的自定义实现已经在某处有相同的实现了,何不直接引用它们?
-
语法:类或对象 :: 方法名;包括静态方法
Comsumer<String> comsumer = string -> System.out.println(string); comsumer.accept(string); // 此处,自定义了接口的方法accept()的实现体为打印参数,这和PrintStream的println()方法一致,所以改为引用println() PrintStream printStream = System.out; comsumer = printStream :: println; // 方法引用 comsumer.accept(string);
3.4 构造器引用
-
当引用的方式是实例的构造方法时,可进化为构造器引用;如comsumer = PrintStream :: new;
4 StreamAPI
-
java.util.stream;对java类库的补充,用于简化处理集合或数组的查找,过滤,映射等;包含了常见API
-
创建方式:List<T> list 或者 T[] array
-
list.stream() :顺序流,list.parallelStream():并行流;返回Stream<T>
-
Arrays.stream(arrays):数组流化需借助Arrays的静态方法
-
Stream.of(可变参数列表):使用本身的of()
-
-
中间操作:
-
filter(predicate):过滤,自定义实现Predicate的lambda实现
-
sorted():排序;无参则自然排序,有参则自定义排序规则
-
结合比较器Comparator,如:list.stream().sorted(Comparator.comparing(User::getCreateTime).collect(Collectors.toList());此时排序能处理User为null即出现空指针异常,但不能处理User对象中的元素出现空指针,需要自己实现:list.stream().sorted(Comparator.comparing(User::getCreateTime, Comparator.nullLast(Date::compareTo))).collect(Collectors.toList());Date为元素createTime的数据类型
-
-
map(Function):建立映射关系,类似接收一个参数作为key,处理的结果作为value
-
flatMap():建立映射
-
distinct():去重;元素需要实现hashCode()和equals()
-
groupBy():分组,用于集合元素的操作特别方便;stream不存储数据,不改变源对象,而是返回一个持有结果的新Stream
-
limit():截断元素,即限制数量
-
skip():跳过元素,即从跳过的下一个开始;元素不足跳过数量时返回空流
-
-
终止操作:stream方法操作是延迟的,即在调用终止操作时,中间操作才开始执行,而不是写一个就调用一个;终止结束后,不可再复用,想用则新建
-
forEach():遍历
-
allMatch(Predicate),anyMatch(),noMatch():全部匹配,至少一个匹配,无匹配
-
findFirst(),findAny():查找第一个,任意元素
-
count():元素个数
-
max(),min():流中最大,小值
-
reduce():规约,结合所有元素
-
collect(Collector):收集,将流转为其他形式
List<Integer> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { list.add(i); } // 过滤即选出大于50的数,以前一个数大于后一个数即逆序的方式排序,限制个数为20个 list.stream() .filter(i -> i > 50) .sorted((order1, order2) -> order2.compareTo(order1)) .limit(20) .forEach(j -> { System.out.println(j); }); // 输出 99 98 97 96 95 94... List<User> list; Stream<User> stream = list.stream(); stream .filter(user -> user.getSalary() > 5000) // user是list中的元素,过虑salary大于5000的用户 .forEach(System.out::println); // 打印user list.stream() // 需要新建stream而不能使用上面的,因为已经终止 .limit(3) .forEach(System.out:println); list.stream() .map(string -> string.toUpperCase()) // string是list中的元素,作为key,转为大写后的值作为value .forEach(System.out:println); list.stream() .map(user -> user.getName()) // 构建一个key为user,value为name的map的流 .filter(name -> name.length() > 3) // 过滤name长度大于3的 .forEach(System.out:println); list.stream() .reduce(0, Integer::sum); list.stream() .filter(user -> user.getSalary() > 5000) .collect(Collectors.toSet()); // 返回set,toList()返回list,toCollection()返回指定类型 // 修改集合中的对象的属性;注意不需要返回值接收 list.stream() .forEach(user -> { if (...) { user.setName(...); } else ... ... });
-
5 Optional< T>
-
java.util.Optional,一个容器,保存T类型的值或null,表示存在与否;为避免空指针异常而设计
-
of(obj):返回指定非null值的Optional
-
ofNullable(obj):返回指定非null值的Optional或空的Optional
-
empty():返回空的Optional
-
orElse(newObj):如果obj为空,则新实例化obj
-
isPresent():判断是否包含对象
-
ifPresent(Consumer):如果值存在则使用该值调用consumer , 否则不做任何事情
-
get():返回对象,null则抛出NoSuchElementException;orElseGet(),orElseThrow()
-
filter(Predicate):如果值存在并且值匹配给定的predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional
-
map(Funciton),flatMap(Function):如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
-
官网:Optional (Java Platform SE 8 )
// 原始判断null if (null != user) return user.getName(); else return null; // 优化 Optional<User> optional = Optional.ifNullable(user); User newUser = optional.orElse(new User("name")); return newUser.getName();
6 接口增强
public interface MyInterface {
// 普通的接口的抽象方法;实现类必须重写抽象方法
void methodAbstract();
// java8提供了接口定义有方法体的静态方法和默认方法;静态方法由接口调用
static void methodStatic() {
System.out.println("静态方法");
}
default void methodDefault() {
System.out.println("默认方法");
}
// Java9提供了方法权限为私有
private void methodPrivate() {
System.out.println("私有方法");
}
}