/**
* 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. 内网渗透-横向移动($IPC&at&schtasks)

    内网渗透-横向移动 #建立ipc连接并将后门添加至计划任务 前置条件:获取到某域主机权限->得到明文或者hash,通过信息收集到的用户列表当做用户名字典->用得到的密码明文当做密码字典 本 ...

  2. Linux的三剑客

    首先,需要介绍一下管道和正则表达式,因为它经常和Linux三剑客一起使用. 一.管道Linux 提供管道符"|",将两个命令隔开,管道符左边命令的输出作为管道符右边命令的输入. c ...

  3. OpenCV on Mac OSX: A step-by-step guide

    I'm using OpenCV for my 4th year design project and setting it up was a huge pain. I had to look thr ...

  4. 如何通过在线CRM提升企业竞争力?

    随着信息技术的快速发展,在线CRM系统也得到了更加广泛的应用,已经在企业中逐渐开始普及.CRM系统对于优化企业流程有着十分重要的意义,它能够让企业的经营管理更加敏捷,并且可以快速地响应企业的业务流程. ...

  5. rabbitmq介绍以及初步使用

    什么是MQ? ​ MQ(Message Queue):翻译为消息队列,通过典型的生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断地从队列中获取消息.因为消息的生产和消费都是异步的,而且只 ...

  6. font 和 text ,cursor

    font:14px/30px/"宋体"这种写法等于 font-size="14px" line-heigiht="30px" font-fa ...

  7. envoy 官方example运行失败问题处理

    镜像内安装包失败处理 方法一:修改Dockerfile,在Dockerfile中增加如下 ubuntu示例 RUN sed -i 's/archive.ubuntu.com/mirrors.aliyu ...

  8. [bug] kibana:prevMsg":"Request Timeout after 3000ms

    ES启动问题,内存不足 https://blog.csdn.net/qq_40907977/article/details/104499178 修改ES启动内存 https://blog.csdn.n ...

  9. Linux Centos7设置UTF-8编码,防止中文乱码

    Linux Centos7设置UTF-8编码,防止中文乱码 # localeLANG=zh_CN.gb2312LC_CTYPE="zh_CN.gb2312"LC_NUMERIC=& ...

  10. 037.Python的UDP语法

    UDP语法 1 创建一个socket的UDP对象 import socket #创建对象 socket.SOCK_DGRAM 代表UDP协议 sk = socket.socket(type=socke ...