/**
* 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. JS中函数定义和使用顺序

    在js中如果定义函数是先声明函数,如: console.log(hello); //然后再去定义: function hello(){ alert("Hello");} 这种是可以 ...

  2. 风变编程(Python自学笔记)第11关-杀死那只“机”生虫

    1.Debug:为程序排除错误. 2.SyntaxError:语法错误. 3.append()函数是列表的一个方法,要用句点.调用,且append()每次只能接受一个参数. 4.解决思路不清的两个工具 ...

  3. Java集合详解(二):ArrayList原理解析

    概述 本文是基于jdk8_271版本进行分析的. ArrayList是Java集合中出场率最多的一个类.底层是基于数组实现,根据元素的增加而动态扩容,可以理解为它是加强版的数组.ArrayList允许 ...

  4. java基础——简易计算器的实现

    计算器: import java.util.Scanner;​public class CalculateDemo {    public static void main(String[] args ...

  5. [bug] HDFS:DataXceiver error processing WRITE_BLOCK operation

    文件格式有误,导致读取错误,我的是把制表符敲成了空格

  6. [Python] 条件 & 循环

    条件语句 不加 () 结尾加 : elif else 和 if 成对使用 省略判断条件 String:空字符串为False,其余为True int:0为False,其余为True Bool:True为 ...

  7. Docker Swarm(十)Portainer 集群可视化管理

    前言 搭建好我们的容器编排集群,那我们总不能日常的时候也在命令行进行操作,所以我们需要使用到一些可视化的工具,Docker图形化管理提供了很多工具,有Portainer.Docker UI.Shipy ...

  8. 创建第一个django工程

    一.环境搭建 使用anaconda + pycharm的环境. 1.创建虚拟环境并安装django1.8的包 # 创建虚拟环境 conda create -n django python=3.6 # ...

  9. CentOS 下解决ssh登录 locale 警告

    最近登录一台CentOS 6机器,发现每次登录都提示如下警告: -bash: warning: setlocale: LC_CTYPE: cannot change locale (en_US.UTF ...

  10. unity中UI坐标转3d世界坐标

    方法: public static Vector3 UIScreenToWorldPoint(Vector3 uiPostion) { uiPostion = UICamera.mainCamera. ...