Java基础-6-函数式接口与Lambda表达式

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层(越下越底层)及相关协议簇

    1. 应用层:

      1. 应用层:TFPT,HTTP,SNMP,FTP,SMTP,DNS,Telnet

      2. 表示层

      3. 会话层

    2. 传输层:TCP,UDP

    3. 网络层:IP,ICMP,RIO,OSPF,BCP,IGMP

    4. 链路层:

      1. 数据链路层

      2. 物理层: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("私有方法");
     }
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值