它不是一种具体的技术,是一种方法论,使用对应提供的函数进行编程,而不是去关心内部的实现。
1·方法没有参数:()->{ }
2·方法有参数:(参数,参数)->{ }
3·如果现在只有一行语句返回:(参数,参数)->语句
内联代码片
。/**
* 接受单个输入参数并且不返回结果的操作。
* 与大多数其他功能接口不同, Consumer预期通过副作用进行操作。
*
* @since 1.8
*/
@FunctionalInterface
public interface Consumer {
/**
* 对给定的参数执行此操作。
*
* @param t the input argument
*/
void accept(T t);
/**
* 返回一个组合的Consumer ,依次执行此操作,然后执行after操作。
* 如果执行任一操作会抛出异常,它将被转发到组合操作的调用者。
* 如果执行此操作会引发异常,则不会执行after操作。
*
* @param 此操作后执行的操作
* @return 一个组成的 Consumer ,依次执行 after操作
* @throws NullPointerException - if after is null
*/
default Consumer andThen(Consumer super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
/**
* 获取一个新的字符串
* @param name
* @param consumer
*/
public static void getNewStr(String name,Consumer consumer){
consumer.accept(name);
}
public static void main(String[] args) {
String name = "张三";
getNewStr(name,(x)-> System.out.println(x+"去吃饭了..."));
//输出结果为:张三去吃饭了...
}
从上述示例可以看出,这个函数相当于预先给你一些默认的操作,如果只要传入相对应的参数进去就能自动帮你实现功能。内联代码片
。@FunctionalInterface
public interface Function {
// 接受输入参数,对输入执行所需操作后 返回一个结果。
R apply(T t);
// 返回一个 先执行before函数对象apply方法,再执行当前函数对象apply方法的 函数对象。
default Function compose(Function super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 返回一个 先执行当前函数对象apply方法, 再执行after函数对象apply方法的 函数对象。
default Function andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
static Function identity() {
return t -> t;
}
}
/**
* 获取一个新的价格
* @param price
* @param function
* @return
*/
static Double getNewPrice(Float price, Function function){
return function.apply(price);
}
public static void main(String[] args) {
Double newPrice = getNewPrice(20.36F, (x) -> (double) x + 30);
System.out.println(newPrice);
//输出结果为:50.36000061035156
}
/**
* 从参数可知,function 第一次已经将float转换成double了,第二次将double转换成float
* 本示例是告诉用法,不要以为是没事转换来转换去
* @param price
* @param function
* @param function2
* @return
*/
static Float getNewPrice(Float price, Function function,Function function2){
return function.andThen(function2).apply(price);
}
public static void main(String[] args) {
Float newPrice = getNewPrice(20.36F, (x) -> (double) x + 30,(x)->(float)(x + 20) );
System.out.println(newPrice);
}
@FunctionalInterface
public interface Supplier {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
public static String getNewStr(Supplier supplier){
return supplier.get();
}
public static void main(String[] args) {
String name = "张三";
String newStr = getNewStr(()->name+"去吃饭了...");
System.out.println(newStr);
//输出结果为:张三去吃饭了...
}
/**
* 执行返回结果
*/
boolean test(T t);
/**
* 多条件同时满足
*/
default Predicate and(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* 执行结果的反转值
* true变成 false ,false 变成true
*/
default Predicate negate() {
return (t) -> !test(t);
}
/**
* 两个条件或者
*/
default Predicate or(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* 是否是同一对象
*/
static Predicate isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
/**
* 获取断言信息
* @param value
* @param predicate
* @return
*/
public static Boolean getPredicate(Integer value, Predicate predicate){
return predicate.test(value);
}
public static void main(String[] args) {
Integer math = 20 ;
Boolean predicate = getPredicate(math, (x) -> x >= 30);
System.out.println(predicate);
}
public static void main(String[] args) {
List studentList = Arrays.asList(new Student("张三", 7, 90.00),
new Student("李四", 6, 80.05),
new Student("王五", 3, 100.00));
//多线程并发情况下能保证线程安全
Collections.synchronizedList(studentList)
//按成绩进行倒叙排列
Collections.sort(studentList,Comparator.comparing(Student::getGrade).reversed());
//遍历新的集合顺序
studentList.forEach(student->{
System.out.println(student.toString());
});
//输出结果为:
//王五年龄是 :3, 分数是:100.0分
//张三年龄是 :7, 分数是:90.0分
//李四年龄是 :6, 分数是:80.05分
}
@Data
@AllArgsConstructor
public static class Student{
private String name;
private Integer age;
private Double grade;
@Override
public String toString() {
return name + "年龄是 :" + age + ", 分数是:" + grade + '分';
}
}
比如在一堆数字中寻找最小值
当这堆数字很大的时候,我们需要去实现多线程去比较的话,需要考虑多线程,线程池以及拆分数据,实现快排等,但是当我们使用JDK8函数式编程的时候可以直接使用一个方法开启 并行 .parallel()
int min = IntStream.of(nums).parallel().min().getAsInt();
比较下函数式编程和命令式编程
int min = IntStream.of(nums).parallel().min().getAsInt();
int minNum = Integer.MAX_VALUE;
for (int num : nums) {
if (num < minNum) {
minNum = num;
}
}
通过上述函数式编程优势很明显,不需要处理内部是怎么实现的,只需要得到一个结果就行了。
Optional 可以省去非空判断,因为内部已经实现了,避免了空指针异常。
方法 | 描述 |
---|---|
of | 把指定的值封装为Optional对象,如果指定的值为null,则抛出NullPointerException |
empty | 创建一个空的Optional对象 |
ofNullable | 把指定的值封装为Optional对象,如果指定的值为null,则创建一个空的Optional对象 |
get | 如果创建的Optional中有值存在,则返回此值,否则抛出NoSuchElementException |
orElse | 如果创建的Optional中有值存在,则返回此值,否则返回一个默认值 |
orElseGet | 如果创建的Optional中有值存在,则返回此值,否则返回一个由Supplier接口生成的值 |
orElseThrow | 如果创建的Optional中有值存在,则返回此值,否则抛出一个由指定的Supplier接口生成的异常 |
filter | 如果创建的Optional中的值满足filter中的条件,则返回包含该值的Optional对象,否则返回一个空的Optional对象 |
map | 如果创建的Optional中的值存在,对该值执行提供的Function函数调用 |
flagMap | 如果创建的Optional中的值存在,就对该值执行提供的Function函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象 |
isPresent | 如果创建的Optional中的值存在,返回true,否则返回false |
ifPresent | 如果创建的Optional中的值存在,则执行该方法的调用,否则什么也不做 |
这个新特性其实是很重要的,它的作用就是在接口上可以定义方法的实现 作为默认方法,这样
Java就可以扩展很多底层接口 比如List接口 ,对其添加了很多default默认方法,这时候List的接口的实现类也不用去修改了。
@FunctionalInterface
interface Interface1 {
int doubleNumber(int i);
default void someMethod(){
System.out.println("Interface1 default Method ");
}
}
@FunctionalInterface
interface Interface1 {
int doubleNumber(int i);
void someMethod();
}
含义:在各种程序元素(定义类、定义接口、定义方法、定义成员变量…)
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)。
标注在类,方法等上面的注解可以重复出现,之前是不允许
getAnnotationsByType(),可以返回某个类型的重复注解,例如Filterable.class.getAnnoation(Filters.class)将返回两个Filter实例,输出到控制台的内容如下所示:
filter1
filter2