/**
* 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. VS里的 代码片段(Code snippet)很有用,制作也很简单

    工欲善其事必先利其器,而 Visual Studio 就是我们的开发利器. 上一篇文章,介绍了一个很棒的快捷键,如果你还没用过这个快捷键,看完之后应该会豁然开朗.如果你已经熟练的应用它,也会温故而知新 ...

  2. C++知识概要

    static的用法和作用 在全局变量前加上关键字 static,全局变量就定义成一个全局静态变量.存储在静态存储区,在整个程序运行期间一直存在.同时全局静态变量在声明他的文件之外是不可见的 在局部变量 ...

  3. Spring的Xml和JavaConfig 扩展你选哪一个?

    引言 上一篇文章我们有怎么介绍到如何通过XML的形式来定义Spring的扩展<Spring面试高频题如何:自定义XML schema 扩展>,好多人都在吐槽现在都什么年代了,xml还有人再 ...

  4. 置的测试文件的大小一定要大过你的内存(最佳为内存的两倍大小),不然linux会给你的读写的内容进行缓存,会使数值非常不准确。

    使用iozone测试磁盘性能   IOzone是一个文件系统测试基准工具.可以测试不同的操作系统中文件系统的读写性能.可以通过 write, re-write, read, re-read, rand ...

  5. 【转载】ltp压力测试结果分析脚本

    博客园 首页 新随笔 联系 管理 订阅 随笔- 8  文章- 0  评论- 0  ltp压力测试结果分析脚本   最近工作性质发生了改变,在做操作系统方面的测试.接手的第一个任务是做ltp stres ...

  6. lighttpd 轻量级WEB服务器

    Lighttpd 是一款开源 Web 服务器软件.Lighttpd 安全快速,符合行业标准,适配性强并且针对高配置环境进行了优化.相对于其它的 Web 服务器而言,Lighttpd 占用内存更少:因其 ...

  7. ThinkPHP无限级分类(递归)

    代码演示 没什么可说的直接看代码 <?php namespace app\controller; class Category { //模拟假数据 protected static functi ...

  8. Go基础结构与类型03---标准输入与输出

    package main import ( "fmt" "strconv" ) //每次接收一个用户输入 func main031() { //定义a, b两个 ...

  9. TVM交叉编译和远程RPC

    TVM交叉编译和远程RPC 本文介绍了TVM中使用RPC的交叉编译和远程设备执行. 使用交叉编译和RPC,可以在本地计算机上编译程序,然后在远程设备上运行它.当远程设备资源受到限制时(如Raspber ...

  10. TensorFlow指定CPU和GPU方法

    TensorFlow指定CPU和GPU方法 TensorFlow 支持 CPU 和 GPU.它也支持分布式计算.可以在一个或多个计算机系统的多个设备上使用 TensorFlow. TensorFlow ...