/**
* java8中的函数式接口,java中规定:函数式接口必须只有一个抽象方法,可以有多个非抽象方法,同时,如果继承实现了
* Object中的方法,那么也是合法的
* <p>
* 函数式接口可以使用lambda来创建
*/
@FunctionalInterface
interface MyService {
void sayMessage(String msg); @Override
boolean equals(Object obj);
} /**
* 入口
* @param args
*/
public static void main(String[] args) {
printSeperator();
testMehtodRef();
printSeperator(); testSupplierConsumer();
printSeperator(); testOptional();
printSeperator(); testStream();
printSeperator();
} /**
* 测试Optional类
*/
private static void testOptional() {
Optional<String> optional1 = Optional.ofNullable(null);
//如果optional确实存在值,那么该函数返回值为true
if (optional1.isPresent()) {
System.out.println("optional1 present!");
} //如果optional没有值,那么默认返回传入的other
String res = optional1.orElse("default");
System.out.println("res's value after orElse:" + res);
try {
/**
* 如果没有该值,那么抛出{@link NoSuchElementException}
*/
res = optional1.orElseThrow();
System.out.println("res's value after orElseThrow:" + res);
} catch (NoSuchElementException e) {
System.out.println("orElseThrow occured!");
} optional1 = Optional.ofNullable("i have a value");
res = optional1.orElse("default");
System.out.println("res's value after orElse:" + res);
} /**
* 测试{@link java.util.function.Supplier} and {@link java.util.function.Consumer}
*/
private static void testSupplierConsumer() {
Supplier<String> supplier1 = new Supplier<String>() {
@Override
public String get() {
return new String("hello world from supplier1");
}
}; //lambda式的supplier,supplier的规定是无参数,且返回一个对象,因此满足该条件
Supplier<String> supplier2 = () -> new String("hello world from supplier2"); //本质上supplier是一个容器,对一个方法的封装
var str1 = getSupplier(supplier1);
var str2 = getSupplier(supplier2);
//方法引用默认返回一个supplier,因为该new不接受任何参数,返回一个对象,因此满足条件
var str3 = getSupplier(String::new);
System.out.println("str1: " + str1 + " str2:" + str2 + " str3:" + str3); /////////////////////////////////////////////////////////////////////////////////////////////
Consumer<String> consumer1 = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.print(s + "|");
}
};
//lambda式的Consumer,Consumer的约定是接受一个参数,返回值为void,因此满足条件
Consumer<String> consumer2 = (s) -> System.out.print(s + "^");
var list = getStrList();
list.forEach(consumer1);
System.out.println();
list.forEach(consumer2);
System.out.println(); /////////////////////////////////////////////////////////////////////////////////////////////
//Predicate谓词接口,用于判断是否符合某个条件,约定是:接受一个参数,返回值为boolean
Predicate<Integer> predicate1 = new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer > 2;
}
}; //lambda式的谓词接口
Predicate<Integer> predicate2 = (num) -> num > 2;
var numList = getIntList();
var res = numList.stream().filter(predicate1).collect(Collectors.toList());
System.out.println(res);
res = numList.stream().filter(predicate2).collect(Collectors.toList());
System.out.println(res); /////////////////////////////////////////////////////////////////////////////////////////////
//Function接口:这是一个功能性的接口,主要用于把一种类型的数据处理完成后,可能得到的结果是另外一种类型
//本质上是上面那些接口的超集,第一个参数为接口的类型,第二个参数为转换后的类型
Function<String, Character> func1 = new Function<String, Character>() {
@Override
public Character apply(String s) {
if (s.length() <= 2) {
return 'a';
}
return s.charAt(2);
}
}; Function<String, Character> func2 = (s) -> {
return s.length() <= 2 ? 'a' : s.charAt(2);
};
var varList = getStrList();
var res2 = varList.stream().map(func1).collect(Collectors.toList());
System.out.println(res2);
res2 = varList.stream().map(func2).collect(Collectors.toList());
System.out.println(res2);
} /**
* 测试{@link java.util.stream.Stream}里面的函数接口,
* Stream里面的函数接口非常的多,类似于SQL,分为两种:
* 1 中间函数 immediate function
* 2 最终函数(规约) terminal function
*/
private static void testStream() {
//将一个数字list,先过滤到大于3的数,然后转换为对应的字母,最后在大写,最后重新收集为一个List
List<Integer> numList = getIntList();
List<String> res = numList.stream().filter((num) -> num > 3).map(num -> String.valueOf((char)('a' + num)))
.map(str -> String.valueOf((char)('A' + str.charAt(0) - 'a'))).collect(Collectors.toList());
System.out.println(res); final int size = 100;
int[] arr = new int[size];
Random random = new Random();
for(int i = 0;i < size;++i){
arr[i] = random.nextInt(1000);
}
//对numArr进行排序,然后得到最前面的5个数据,最后得到最大值
var res2 = Arrays.stream(arr).sorted().limit(5).min();
System.out.println("res2:"+ res2.orElseThrow());
} /**
* 辅助类
*
* @param supplier
* @param <T>
* @return
*/
private static <T> T getSupplier(Supplier<T> supplier) {
return supplier.get();
} /**
* 测试方法引用的用法
*/
private static void testMehtodRef() {
List<String> strs = new ArrayList<>();
strs.add("one");
strs.add("two");
strs.add("three");
strs.add("four"); //printSomething本质上是一个Consumer
strs.forEach(HelloJava8::printSomething);
System.out.println();
} /**
* 打印一些东西
*
* @param s
*/
private static void printSomething(String s) {
System.out.print(s + "\t");
} private static void printSeperator() {
System.out.println(SEPERATOR);
} /**
* 辅助方法,获辅助list
*
* @return
*/
private static List<String> getStrList() {
List<String> strs = new ArrayList<>();
strs.add("one");
strs.add("two");
strs.add("three");
strs.add("four");
return strs;
} /**
* 获取辅助list
*
* @return
*/
private static List<Integer> getIntList() {
List<Integer> intList = new ArrayList<>();
for (int i = 1; i <= 10; ++i) {
intList.add(i);
}
return intList;
}

Java8新特性代码示例(附注释)- 方法引用,Optional, Stream的更多相关文章

  1. Java8新特性(三)之方法引用和构造器引用

    1.使用场景 当要传递给Lambda体的操作,已经存在实现的方法了,就可以使用方法引用.(抽象方法的参数列表  必须与方法引用方法的参数列表保持一致) 2. 语法 使用操作符[::]将方法名和对象或类 ...

  2. 【Java8新特性】- 接口中默认方法修饰为普通方法

    Java8新特性 - 接口中默认方法修饰为普通方法 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学 ...

  3. java8的新特性之lambda表达式和方法引用

    1.1. Lambda表达式 通过具体的实例去体会lambda表达式对于我们代码的简化,其实我们不去深究他的底层原理和背景,仅仅从用法上去理解,关注两方面: lambda表达式是Java8的一个语法糖 ...

  4. JDK1.8新特性之(二)--方法引用

    在上一篇文章中我们介绍了JDK1.8的新特性有以下几项. 1.Lambda表达式 2.方法引用 3.函数式接口 4.默认方法 5.Stream 6.Optional类 7.Nashorm javasc ...

  5. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第4节 方法引用_7方法引用_数组的构造器引用

    先创建函数式接口 创建测试类 打印长度是10...... 方法引用优化

  6. C# 4.0四大新特性代码示例与解读

    摘要:今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 之前的文章中,我们曾介绍过C#的历史及C# 4.0新增特性,包括:dynamic. 命名和可选参数.动态导入以及协变和逆变等. ...

  7. Java8新特性之四:接口默认方法和静态方法

    在JDK1.8以前,接口(interface)没有提供任何具体的实现,在<JAVA编程思想>中是这样描述的:"interface这个关键字产生了一个完全抽象的类,它根本就没有提供 ...

  8. java8新特性:接口的默认方法与静态方法

    接口中一共可以定义三种方法: 1.抽象方法,也就是需要实现者必须实现的方法,最常见的那种 2.默认方法,不需要实现者实现 3.静态方法,不需要实现者实现 默认方法: 允许在已有的接口中添加新方法,而同 ...

  9. Java8新特性之接口defualt,static方法

    简介 作用 Java8中接口引入了defualt,static两种方法提供默认实现,彻底打破了接口不能有默认实现的规定 static 让接口类似于工具类,提供一些静态方法 static方法不会被子类继 ...

随机推荐

  1. JVM核心技术(第一篇)

    目录 Java基础知识 一. 字节码技术 二.JVM类加载器 类的加载时机 三.JVM内存结构 四.JVM启动参数 4.1 系统属性参数 4.2 运行模式 4.3 堆内存 4.4 GC相关 4.5 分 ...

  2. OCR横向评测 -- 软工案例分析

    目录 第一部分 调研&评测 使用感受 1. 使用门槛 2. 界面设计 3. 数据标注 4. 模型训练 5. 模型预测 6. 体验评价与改进建议 好的方面: 可能需要改进的方面: 7. BUG反 ...

  3. CSS3边界图片

    目录 border-image border-image-slice border-image-width border-image-outset border-image-repeat border ...

  4. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)

    一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)     概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...

  5. 搭建LAMP环境部署GLPI资源管理系统

    搭建LAMP环境部署GLPI资源管理系统 一.关闭防火墙和Selinux [root@localhost ~]# systemctl disable --now firewalld [root@loc ...

  6. LDAP协议入门

    LDAP协议入门(轻型目录访问协议) LDAP简介 轻型目录访问协议,全称:Lightweight Directory Access Protocol,缩写:LDAP,它是基于X.500标准的,但是简 ...

  7. 自用Chrome插件推荐【附教程及下载】

    自用Chrome插件推荐[附教程及下载] 豆子   1,675 人赞同了该文章 2019.11.03更新 原文同步发布在我的个人博客 Chrome插件自用​blog.douzi.work 都是我自己一 ...

  8. Redis 为什么使用跳跃表

    引言 跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的. 什么是跳跃表 对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个 ...

  9. IDEA workspace.xml 在 git 中无法忽略 ignore 问题

    问题描述 关于 .idea 的文件夹中的 workspace.xml 设置 ignore 之后每次 commit 依旧提示需要提交改变,这就会导致, 每次merge就会导致提示"本地文件改变 ...

  10. S11 Linux系统管理命令

    11.1 lsof:查看进程打开的文件 11.2 uptime:显示系统的运行时间及负载 11.3 free:查看系统内存信息 11.4 iftop:动态显示网络接口流量信息 11.5 vmstat: ...