IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 函数式接口与Stream流 -> 正文阅读

[Java知识库]函数式接口与Stream流

函数式接口

函数式接口:有且仅有一个抽象方法的接口

java中的函数式编程体现的就是lambda表达式,所以函数式解救就是可以适用于lambda使用的接口

只有确保接口中有且仅有一个抽象方法,java中的lambda才能顺利的进行推导

  • 如何检测一个接口是不是函数式接口呢?
  1. @FunctionanInterface

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

    • 注意

    我们自己定义函数式接口的时候@FunctionalInterface是可以选择的,就算我们不写这个注解,只要保证满足函数式接口定义的条件、也照样是函数式接口,但是,建议加上注解

package Demo26;
@FunctionalInterface
public interface InterfaceDemo {
    void  show();

}
package Demo26;

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

函数式接作为方法的参数

需求

  • 定义一个类(RunnableDemo),在类中提供两个方法

一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口

一个方法是主方法,在主方法中调用startThread方法

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

  • startThread()->System.out.println(Thread.currentThread().getName()+“线程启动了”);
package Demo27;

public class Demo27 {
    public static void main(String[] args) {
                //在主方法中调用startThread方法
        //匿名内部类方式
        startThread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"线程启动了");
            }
        });
        startThread(()->System.out.println(Thread.currentThread().getName()+"线程启动了"));
        }

    private static void startThread(Runnable r){
//        Thread t = new Thread(r);
//        t.start();
        new Thread(r).start();
    }
}

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

需求

  • 定义一个类(ComparatorDemo),在类中提供两个方法

    一个方法是:ComparatorgetComparator() 方法返回值Comparator是一个函数式接口

    一个方法是主方法,在主方法中调用getComparator方法

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

    • private static ComparatorgetComparator(){return(s1,s2) -> s1.length()-s2.length()}
package Demo28;

import Demo25.Java_2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

public class ComparatorDemo {
    public static void main(String args[]) {
        ArrayList<String> array = new ArrayList<String>();
        array.add("cccc");
        array.add("aa");
        array.add("b");
        array.add("ddd");
        System.out.println("排序前"+array);
        Collections.sort(array,getComparator());
        System.out.println("排序后"+array);
    }


    private static Comparator<String> getComparator() {
//        //匿名内部类方式实现
//        Comparator<String> comp = new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.length() - s2.length();
//            }
//        };
        return comp;
//        return  new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.length() - s2.length();
//            }
//        };
//        return (String s1,String s2 ) ->{return  s1.length()-s2.length();
//        };
        return (s1,s2) ->{return  s1.length()-s2.length();
        };
    }
}

常用函数式接口—Supplier

Supplier:包含一个无参方法

  • T get():获得结果
  • 该方法不需要参数,他会安好某种实现逻辑(由lambda表达式实现)返回一个数据
  • Supplier接口也被称为生产性接口,如果我们指定了接口是泛型说明类型,那么接口中的get方法就会产生说明类型的数据供我们使用
package Demo1;

import java.util.function.Supplier;

public class Demo26 {
    public static void main(String[] args) {
        Integer I = getInteger(() -> 30);
        System.out.println(I);
        String s = getSting(() -> {return "pofen";});
    }
    private  static Integer getInteger(Supplier<Integer> sup){
        return sup.get();
    }
    public static String getSting(Supplier<String> sup){
        return  sup.get();
    }

}
  • 练习
  • 定义一个类(Demo27)
    1. 一个方法是:int getMax(supplier sup) 用于返回一个int数组中的最大值
    2. 一个方法是主方法,在主方法中调用getMax方法
package Demo1;

import java.util.function.Supplier;

public class Demo27 {
    public static void main(String[] args) {
        int[] arr ={19,26,25,61,48};
        int maxValue = getMax(() -> {
            int max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                if (arr[i]>max){
                    max = arr[i];
                }
            }
            return  max;
        });
        System.out.println(maxValue);
}
//返回int数组最大值
private static int getMax(Supplier<Integer> sup){
    return  sup.get();
}
}

函数式接口—predicate接口

predicate常用的四个方法

  • boolean test(T t):对给定的参数进行判断(判断逻辑有lambda表达式实现),返回一个布尔值
  • default predicate negate():返回一个逻辑的否定,对应逻辑非
  • default predicate and (Predicate other):返回一个组合判断,对应短路与
  • default predicate or (predicate other):返回一个组合判断,对应短路或
  • predicate接口通常用于判断参数是否满足指定条件
package Demo1;

import java.util.function.Predicate;

public class Demo28 {
    public static void main(String[] args) {
        boolean b1 = checkString("hello",(String s ) ->{return  s.length()>8;});
        System.out.println(b1);
        boolean b2 = checkString("helloworld",s -> s.length()>8);
        System.out.println(b2);
        boolean b3 = checkString("hello",s -> s.length()>8,s -> s.length()<15);
        System.out.println(b3);
    }
    //同一个字符串给出两种不同的判断条件,最后把这两个判断的结构做逻辑运算并且返回最终结果
    private static  boolean checkString(String s ,Predicate<String> pre1,Predicate<String> pre2){
//        boolean b1 = pre1.test(s);
//        boolean b2 = pre1.test(s);
//        boolean b = b1&&b2;
//        return  b ;
       // return  pre1.and(pre2).test(s);
        return  pre1.or(pre2).test(s);

    }
    //判断给定字符串是否满足需求
    private  static boolean checkString(String s , Predicate<String> pre){
       // return pre.test(s);
        return pre.negate().test(s);
    }
}

Function接口

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

  • R apply(T t ):将此函数应用于给定的参数
  • default Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
  • Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑有lambda表达式实现),然后返回一个新的值
package Demo1;

import java.util.function.Function;

public class Demo29 {
    public static void main(String[] args) {
//        convert("100",(String s )-> {
//            return  Integer.parseInt(s);
//        });

        convert("100", s -> Integer.parseInt(s));
        // convert("100",Integer::parseInt);\
        convert(100, i -> String.valueOf(i + 566));
        convert("100",s -> Integer.parseInt(s),i -> String.valueOf(i+566));
    }

    //定义一个方法,把一个字符串转换 int 类型,在控制台输出
    private static void convert(String s, Function<String, Integer> fun) {
        int i = fun.apply(s);
        System.out.println(i);
    }

    //定义一个方法,把一个int类型的数据加上一个整数之后,转换为字符串在控制台输出
    private static void convert(int i, Function<Integer, String> fun) {
        String s = fun.apply(i);
        System.out.println(s);
    }

//定义一个方法,把一个字符串转换为int类型,吧int类型的数据加上一个整数之后,转为字符串在控制台输出
private static  void convert(String s ,Function<String,Integer> fun1 ,Function<Integer,String> fun2){
//      Integer i = fun1.apply(s);
//      String ss = fun2.apply(i);
//    System.out.println(ss);
     String ss = fun1.andThen(fun2).apply(s); 
    System.out.println(ss);
}
}

Stream流

需求:

  • 创建一个集合,储存多个字符串元素
  • 把集合中所有以张开头的元素存储到一个新的集合
  • 把张开头的集合中长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合
package Demo1;

import java.util.ArrayList;

public class Demo30 {
    public static void main(String[] args) {

    ArrayList<String> list = new ArrayList<String>();
    list.add("林青霞");
    list.add("张曼玉");
    list.add("王祖贤");
    list.add("柳岩");
    list.add("张敏");
    list.add("张无忌");
    //把集合中所有以栈开头的元素储存到一个新的集合
        ArrayList<String> zhanglist = new ArrayList<>();
        for(String s : list){
            if(s.startsWith("张")){
                zhanglist.add(s);
            }
        }
        ArrayList<String> threelist = new ArrayList<>();
        for (String s : zhanglist) {
            if (s.length() == 3) {
                threelist.add(s);
            }
        }
            for (String s : threelist){
                System.out.println(s);
            }

//        System.out.println(threelist);
        System.out.println("-------------------");
        //stream流改进
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s .length()==3).forEach(s -> System.out.println(s));
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s .length()==3).forEach(System.out::println);
    }
}

使用stream流的方式完成过滤操作

list.stream().filter(s -> s.startsWith("张")).filter(s -> s .length()==3).forEach(System.out::println);
  • 直接阅读代码的字面上意思即可完美展示无关逻辑方式的语义:生成流,过滤姓张,过滤长度为3,逐一打印

Stream流的生成方式

Stream流的使用

  • 生成流

通过数据源(集合,数组等)生成流

list.stream()

  • 中间操作

一个流后面可以跟随0个或者多个中间操作,其目的主要是打开流,作出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用

filter()

  • 总结操作

一个流只能有一个终结操作,当这个操作执行后,流就被使用“光”了,无法再被操作,所以这必定是流的最后一个操作

foreach()

Sream常见的生成方式

  • Collection体现的集合可以使用默认方法stream()生成流

default Stream stream()

  • Map体系的集合间接生成流
  • 数组可以通过Stream接口静态方法of(T…values)生成流
package Demo1;

import java.util.*;
import java.util.stream.Stream;

public class Demo31 {
    public static void main(String[] args) {
        //collection体系的集合可以使用默认方法stream()流
        List<String> list = new ArrayList<>();
        Stream<String> listStrema = list.stream();

        Set<String> set = new HashSet<>();
        Stream<String> setStream = set.stream();

        //map体系的集合间接生成流

        Map<String,Integer> map = new HashMap<>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String,Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Stream接口的静态方法(T...values)生成流
        String[] strArray = {"hello","word","java"};
        Stream<String> strArrayStream = Stream.of(strArray);
        Stream<String> strArraySAtream2 = Stream.of("hello","woeld","java");
        Stream<Integer> intStream = Stream.of(10,20,30);

    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:19:04  更:2021-09-23 11:21:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:24:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码