10.1、函数式接口

10.1.1、概述

有且仅有一个抽象方法的接口,并且可以通过在类上标注@FunctionalInterface注解进行检测,建议自定义的函数式接口都加上这个注解

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

public class Main {
public static void main(String[] args) {
// 匿名内部类的方式
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程启动了");
}
});
// Lambda表达式方式
startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
} private static void startThread(Runnable r) {
new Thread(r).start();
}
}

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; public class Main {
public static void main(String[] args) {
ArrayList<String> array1 = new ArrayList<String>();
array1.add("cccc");
array1.add("aaa");
array1.add("bb");
array1.add("d");
System.out.println("排序前:" + array1);
Collections.sort(array1, getComparator1());
System.out.println("排序后:" + array1); ArrayList<String> array2 = new ArrayList<String>();
array2.add("cccc");
array2.add("aaa");
array2.add("bb");
array2.add("d");
System.out.println("排序前:" + array2);
Collections.sort(array2, getComparator2());
System.out.println("排序后:" + array2);
} // 匿名内部类的方式实现
private static Comparator<String> getComparator1() {
return new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
};
} // Lambda表达式方式实现
private static Comparator<String> getComparator2() {
return (s1, s2) -> s1.length() - s2.length();
}
}

10.1.4、四大内置核心函数式接口

10.1.4.1、Supplier接口

import java.util.function.Supplier;

public class Main {
public static void main(String[] args) {
String s = getString(() -> "林青霞");
System.out.println(s);
Integer i = getInteger(() -> 30);
System.out.println(i);
} // 定义一个方法,返回一个整数数据
private static Integer getInteger(Supplier<Integer> sup) {
return sup.get();
} // 定义一个方法,返回一个字符串数据
private static String getString(Supplier<String> sup) {
return sup.get();
}
}

10.1.4.2、Consumer接口

import java.util.function.Consumer;

public class Main {
public static void main(String[] args) {
operatorString("林青霞", s -> System.out.println(s));
operatorString("林青霞", s -> System.out.println(new StringBuilder(s).reverse().toString()));
operatorString("林青霞",
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);
}
}

10.1.4.3、Predicate接口

import java.util.function.Predicate;

public class Main {
public static void main(String[] args) {
boolean b1 = checkString("helloworld", s -> s.length() > 8);
System.out.println(b1);
boolean b2 = checkStringNot("helloworld", s -> s.length() > 8);
System.out.println(b2);
boolean b3 = checkStringAnd("helloworld", s -> s.length() > 8, s -> s.length() < 10);
System.out.println(b3);
boolean b4 = checkStringOr("helloworld", s -> s.length() > 8, s -> s.length() < 10);
System.out.println(b4);
} // 定义一个方法,对给定的参数进行判断
private static boolean checkString(String s, Predicate<String> pre) {
return pre.test(s);
} // 定义一个方法,返回一个逻辑的否定,对应逻辑非
private static boolean checkStringNot(String s, Predicate<String> pre) {
return pre.negate().test(s);
} // 定义一个方法,返回一个组合判断,对应短路与
private static boolean checkStringAnd(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.and(pre2).test(s);
} // 定义一个方法,返回一个组合判断,对应短路或
private static boolean checkStringOr(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.or(pre2).test(s);
}
}

10.1.4.4、Function接口

import java.util.function.Function;

public class Main {
public static void main(String[] args) {
convert("100", s -> Integer.parseInt(s));
convert(100, i -> String.valueOf(i));
convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i));
} // 定义一个方法,把一个字符串转换为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) {
String ss = fun1.andThen(fun2).apply(s);
System.out.println(ss);
}
}

10.2、Stream流

10.2.1、概述

流(Stream)是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。集合讲的是数据,流讲的是计算

10.2.2、操作步骤

  1. 获流对象:一个数据源(如:集合、数组),获取一个流(如:串行流、并行流、无限流)

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import java.util.UUID;
    import java.util.stream.DoubleStream;
    import java.util.stream.IntStream;
    import java.util.stream.LongStream;
    import java.util.stream.Stream; public class Main {
    public static void main(String[] args) {
    // Collection体系的集合直接生成流
    List<String> list = new ArrayList<String>();
    Stream<String> listStream = list.stream();// 顺序流
    Stream<String> parallelListStream = list.parallelStream(); // 并行流
    Set<String> set = new HashSet<String>();
    Stream<String> setStream = set.stream();// 顺序流
    Stream<String> parallelSetStream = set.parallelStream();// 并行流 // Map体系的集合间接生成流
    Map<String, Integer> map = new HashMap<String, Integer>();
    Stream<String> keyStream = map.keySet().stream();// 顺序流
    Stream<String> parallelKeyStream = map.keySet().parallelStream();// 并行流
    Stream<Integer> valueStream = map.values().stream();// 顺序流
    Stream<Integer> parallelValueStream = map.values().parallelStream();// 并行流
    Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();// 顺序流
    Stream<Entry<String, Integer>> parallelEntryStreamStream = map.entrySet().parallelStream();// 并行流 // 数组可以通过Arrays类的静态方法Arrays.stream(T[] array)生成流
    int[] intArray = { 10, 20, 30 };
    IntStream intStream = Arrays.stream(intArray);// 顺序流
    IntStream parallelIntStream = intStream.parallel();// 并行流
    long[] longArray = { 10L, 20L, 30L };
    LongStream longStream = Arrays.stream(longArray);// 顺序流
    LongStream parallelLongStream = longStream.parallel();// 并行流
    double[] doubleArray = { 10.1, 20.2, 30.3 };
    DoubleStream doubleStream = Arrays.stream(doubleArray);// 顺序流
    DoubleStream parallelDoubleStream = doubleStream.parallel();// 并行流 // 数组可以通过Stream接口的静态方法Stream.of(T... values)生成流
    Stream<String> strArrayStream = Stream.of("hello", "world", "java");// 顺序流
    Stream<String> parallelStrArrayStream = strArrayStream.parallel();// 并行流
    Stream<Integer> intArrayStream = Stream.of(10, 20, 30);// 顺序流
    Stream<Integer> parallelIntArrayStream = intArrayStream.parallel();// 并行流
    Stream<Long> longArrayStream = Stream.of(10L, 20L, 30L);// 顺序流
    Stream<Long> parallelLongArrayStream = longArrayStream.parallel();// 并行流
    Stream<Double> doubleArrayStream = Stream.of(10.1, 20.2, 30.3);// 顺序流
    Stream<Double> parallelDoubleArrayStream = doubleArrayStream.parallel();// 并行流 // 创建无限流
    Stream<Integer> iterateStream = Stream.iterate(0, i -> i + 2);
    iterateStream.limit(10).forEach(System.out::println);
    Stream<UUID> generateStream = Stream.generate(UUID::randomUUID);
    generateStream.limit(10).forEach(System.out::println);
    }
    }
  2. 中间操作:一个中间操作链,对数据源的数据进行处理

    • filter()
    • limit()
    • skip()
    • distinct()
    • sorted()
    • map()
    • mapToInt()
    • mapToLong()
    • mapToDouble()
    • flatMap()
    • flatMapToInt()
    • flatMapToLong()
    • flatMapToDouble()
    • peek()
  3. 终止操作:一个终止操作,执行中间操作链并产生结果

    • forEach()
    • forEachOrdered()
    • count()
    • min()
    • max()
    • reduce()
    • collect()
    • toArray()
    • findFirst()
    • findAny()
    • anyMatch()
    • allMatch()
    • noneMatch()

10.2.3、代码演示

filter代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
// 需求1:把list集合中以张开头的元素在控制台输出
list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
System.out.println("----------");
// 需求2:把list集合中长度为3的元素在控制台输出
list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
System.out.println("----------");
// 需求3:把list集合中以张开头的且长度为3的元素在控制台输出
list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
}
}

limit&skip代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
// 需求1:取前3个数据在控制台输出
list.stream().limit(3).forEach(System.out::println);
System.out.println("----------");
// 需求2:跳过3个元素,把剩下的元素在控制台输出
list.stream().skip(3).forEach(System.out::println);
System.out.println("----------");
// 需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
list.stream().skip(2).limit(2).forEach(System.out::println);
}
}

distinct代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("林青霞");
list.add("张曼玉");
list.add("张曼玉");
list.add("王祖贤");
list.add("王祖贤");
list.add("柳岩");
list.add("柳岩");
list.add("张敏");
list.add("张敏");
list.add("张无忌");
list.add("张无忌");
// 需求1:把集合元素在控制台输出,要求字符串元素不能重复
list.stream().distinct().forEach(System.out::println);
}
}

sorted代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("linqingxia");
list.add("zhangmanyu");
list.add("wangzuxian");
list.add("liuyan");
list.add("zhangmin");
list.add("zhangwuji");
// 需求1:按照字母顺序把数据在控制台输出
list.stream().sorted().forEach(System.out::println);
System.out.println("----------");
// 需求2:按照字符串长度把数据在控制台输出
list.stream().sorted((s1, s2) -> {
int num1 = s1.length() - s2.length();
int num2 = num1 == 0 ? s1.compareTo(s2) : num1;
return num2;
}).forEach(System.out::println);
}
}

map&mapToInt&mapToLong&mapToDouble代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
// 需求1:将集合中的字符串数据转换为整数之后在控制台输出
list.stream().map(Integer::parseInt).forEach(System.out::println);
System.out.println("----------");
// 需求2:将集合中的字符串数据转换为Integer之后在控制台输出
list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
System.out.println("----------");
// 需求3:将集合中的字符串数据转换为Long之后在控制台输出
list.stream().mapToLong(Long::parseLong).forEach(System.out::println);
System.out.println("----------");
// 需求4:将集合中的字符串数据转换为Double之后在控制台输出
list.stream().mapToDouble(Double::parseDouble).forEach(System.out::println);
}
}

forEach&forEachOrdered&count代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
// 需求1:把集合中的元素在控制台输出
list.stream().forEach(System.out::println);
System.out.println("----------");
// 需求2:把集合中的元素在控制台输出
list.stream().forEachOrdered(System.out::println);
System.out.println("----------");
// 需求3:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
long count = list.stream().filter(s -> s.startsWith("张")).count();
System.out.println(count);
}
}

max&min代码演示:

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
// 创建一个集合,存储多个整数元素
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
// 需求1:获取集合中的最大值在控制台输出
Integer max = list.stream().max(Integer::compareTo).get();
System.out.println(max);
// 需求2:获取集合中的最小值在控制台输出
Integer min = list.stream().min(Integer::compareTo).get();
System.out.println(min);
}
}

第十章 函数式接口&Stream流的更多相关文章

  1. 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)

    小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优)  //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ...

  2. 13函数式编程&Stream流

    13.1常用的函数式接口总结   接口名称 方法名称 抽象/默认  延迟/终结 方法描述 Supplier get 抽象 终结 供给型接口,无参有返回值,主要用于 Consumer accept 抽象 ...

  3. JavaSE23-函数式接口&Stream流

    1.函数式接口 1.1 函数式接口概述 概念 有且仅有一个抽象方法的接口 如何检测一个接口是不是函数式接口 @FunctionalInterface 放在接口定义的上方:如果接口是函数式接口,编译通过 ...

  4. 函数式接口与Stream流

    lambda表达式是jdk8的特性.lambda表达式的准则是:可推断,可省略. 常规代码写一个多线程 public class Main { public static void main(Stri ...

  5. Java的lamda表达式/函数式接口/流式计算

    在我们看他人code的时候经常会看到,可能会经常看到lambda表达式,函数式接口,以及流式计算.在刚接触这些新功能时,也觉得真的有必要吗?但是现在写多了,发现这个功能确实能简化代码结构,提升编码效率 ...

  6. Java 8-Lambda表达式、方法引用、标准函数接口与流操作、管道操作之间的关系

    1.Lambda表达式与接口之间的关系 只要Lambda表达式的声明形式与接口相一致,在很多情况下都可以替换接口.见如下代码 Thread t1 = new Thread(new Runnable() ...

  7. [一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念

      本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程?   java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的 ...

  8. JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用

    jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default   Lambda表达式     L ...

  9. 常用函数式接口与Stream API简单讲解

    常用函数式接口与Stream API简单讲解 Stream简直不要太好使啊!!! 常用函数式接口 Supplier<T>,主要方法:T get(),这是一个生产者,可以提供一个T对象. C ...

随机推荐

  1. PKIX

    这是证书认证不通过的问题,对https协议免认证 http://blog.csdn.net/zziamalei/article/details/46520797 使用上面的方法时,使用spring的& ...

  2. 认识Eureka (F版)

    Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态).使用Sprin ...

  3. .gitkeep文件

    git 默认不会对空文件夹进行追踪: 但某些项目某些文件夹对整体框架是必不可少的,就算是空也得有: 怎么办呢?在这个文件夹下添加一个[.gitkeep]文件,这样就可以同步该文件夹了. (完)

  4. 阿里云Linux CentOS8.1 用 xshell 上传和下载文件

    下载: 例如有一个script 文件夹,我们要把它打包成 tar文件,并下载到本地.具体命令如下: 1.进入script 所在的目录,先打包,命令如下: tar -cvf script.tar scr ...

  5. 我打算用JAVA实现GB/T32960 监控平台的tcp server

    之前是用golang写得 ,因为对golang不是很熟练,打算基于netty再写一个,开源出来. 如果近期时间宽裕,就准备着手了. 有兴趣的朋友也可以留言一起做.

  6. Code Forces 833 A The Meaningless Game(思维,数学)

    Code Forces 833 A The Meaningless Game 题目大意 有两个人玩游戏,每轮给出一个自然数k,赢得人乘k^2,输得人乘k,给出最后两个人的分数,问两个人能否达到这个分数 ...

  7. Blazor带我重玩前端(三)

    写在前面 需要升级VS2019以及.NET Core到最新版(具体的最低支持,我已经忘了,总是越新支持的就越好),以更好的支持自己开发Blazor项目. WebAssembly 搜索Blazor模板 ...

  8. shell进阶篇之数组应用案例

    数组中可以存放多个值. Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小. 与大部分编程语言类似,数组元素的下标由0开始. Shell 数组用括号来表示,元素用"空格 ...

  9. Qt_Demo3:实现棋盘

    1  简介 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=53 说明:实现一个8*8的棋盘,点击棋盘的任意位置显示一个表情,并打印出当前的坐标( ...

  10. 实现 (5).add(3).minus(2) 功能

    Number.prototype.add = function (number) { if (typeof number !== 'number') { throw new Error('请输入数字- ...