java8函数式编程

编程

一 、什么是函数式编程

1、每个人对函数式编程的理解不尽相同。

   但其核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值。

  • Lambda 表达式是一个匿名方法,将行为像数据一样进行传递。  

2、编写不同形式的Lambda表达式:

Runnable noArguments = () -> System.out.println("Hello World");

所示的 Lambda 表达式不包含参数,使用空括号 () 表示没有参数。该 Lambda 表达式 实现了 Runnable 接口,该接口也只有一个 run 方法,没有参数,且返回类型为 void。

ActionListener oneArgument = event -> System.out.println("button clicked");

所示的 Lambda 表达式包含且只包含一个参数,可省略参数的括号,这和例 2-2 中的 形式一样

 

Runnable multiStatement = () -> {

System.out.print("Hello");

System.out.println(" World");

};

Lambda 表达式的主体不仅可以是一个表达式,而且也可以是一段代码块,使用大括号 ({})将代码块括起来,如上图所示。该代码块和普通方法遵循的规则别无二致,可以用返 回或抛出异常来退出。只有一行代码的 Lambda 表达式也可使用大括号,用以明确 Lambda

表达式从何处开始、到哪里结束

BinaryOperator<Long> add = (x, y) -> x + y;

ambda 表达式也可以表示包含多个参数的方法,如上所示。这时就有必要思考怎样去阅 读该 Lambda 表达式。这行代码并不是将两个数字相加,而是创建了一个函数,用来计算 两个数字相加的结果。变量 add 的类型是 BinaryOperator<Long>,它不是两个数字的和, 而是将两个数字相加的那行代码。

BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

所有 Lambda 表达式中的参数类型都是由编译器推断得出的。这当然不错,但有时最好也可以显式声明参数类型,此时就需要使用小括号将参数括起来,多个参数的情况也是如此.

final String[] array = { "hello", "world" };

等号右边的代码并没有声明类型,系统根据上下文推断出类型信息

artist -> artist.getName()

简化成(方法引用)

Artist::getName

创建一个 Artist 对象

(name, nationality) -> new Artist(name, nationality)

简化成

Artist::new (这种方式创建数组String[]::new)

直接调用foo方法

x -> foo(x)

3、 引用值,而不是变量

String name = getUserName();

button.addActionListener(event -> System.out.println("hi " + name));

Lambda 表达式中引用的局部变量必须是 final 或既成事实上的 final 变量,,即该变量不能被多次赋值!

4、函数接口

  • 函数接口指仅具有单个抽象方法的接口,用来表示Lambda表达式的类型。

Predicate 接口的源码,接受一个对象,返回一个布尔值

public interface Predicate<T> {

boolean test(T t);

}

Predicate<Integer> atLeast5 = x -> x > 5;

二、类库

1、在代码中使用Lambda表达式

使用 isDebugEnabled 方法降低日志性能开销

Logger logger = new Logger(); if (logger.isDebugEnabled()) {

logger.debug("Look at this: " + expensiveOperation()); }

使用 Lambda 表达式简化日志代码 Logger logger = new Logger();

logger.debug(() -> "Look at this: " + expensiveOperation());

 

2、其他方法

package com.dy.spring.boot.domian;

import java.util.*;

import java.util.stream.Collectors;

import java.util.stream.Stream;

public class Person {

private Integer id;

private String name;

public Person(Integer id, String name) {

this.id = id;

this.name = name;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public static void main(String[] args) {

List<Person> list = new ArrayList();

list.add(new Person(1, "name1"));

list.add(new Person(2, "name2"));

list.add(new Person(3, "name3"));

//collect(toList())----------由 Stream 里的值生成一个列表,是一个及早求值操作----------start

List<String> collected = Stream.of("a", "b", "c").collect(Collectors.toList());

//collect(toList())----------由 Stream 里的值生成一个列表,是一个及早求值操作----------end

//map +++++++++++++++++++++++++++++++++start

//如果有一个函数可以将一种类型的值转换成另外一种类型,map 操作就可以 使用该函数,将一个流中的值转换成一个新的流

List<String> names = list.stream().map(Person::getName).collect(Collectors.toList());

//map +++++++++++++++++++++++++++++++++end

//filter----------------------start-----------------

//过滤集合中的元素,去除元素中的集合。

List<Person> p2_list = list.stream().filter(o -> o.getId() > 1).collect(Collectors.toList());

p2_list.stream().forEach(p -> {

System.out.println(p.name);

});

//统计集合元素满足条件的数量

long count = list.stream()

.filter(p -> p.id > 1)

.count();

System.out.println("count = " + count);

//filter 时进行其他操作

count = list.stream()

.filter(p -> {

System.out.println(p.name);

return p.id > 1;

})

.count();

//filter----------------------end------------------

//flatMap 方法可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream~~~~~~~~~~~~~~~~~~~~~~~~start

//map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap

Stream<List<Integer>> inputStream = Stream.of(

Arrays.asList(1),

Arrays.asList(2, 3),

Arrays.asList(4, 5, 6)

);

List<Integer> outList = inputStream.flatMap((childList) -> childList.stream()).collect(Collectors.toList());

System.out.println("flatMap-> " + outList);

list.stream().peek(o -> System.out.println(o.getId()));

//flatMap 方法可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream~~~~~~~~~~~~~~~~~~~~~~~~end

//max和min、reduce*******************start

// Stream 中的 findAny等方法等返回 Optional 值。还有例如 IntStream.average() 返回 OptionalDouble 等等。

// 可以将集合中的元素组合起来,例如:字符串拼接,数值的sum,min,max,average都是特殊的reduce。

System.out.println("findFirst:" + list.stream().findFirst().get().getName());

System.out.println("max : " + list.stream().max(Comparator.comparing(p->p.id)).get().name);

System.out.println("min : " + list.stream().min(Comparator.comparing(p->p.id)).get().name);

//reduce 操作可以实现从一组值中生成一个值

int sum = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);

//结果是0+1+2+3=6

System.out.println("reduce : " +sum);

//max和min *******************end

//imit返回Stream的前n个元素,skip则是舍弃前n个元素

//[3,2,1]

System.out.println(Arrays.asList(5, 4, 3, 2, 1).stream().skip(2).collect(Collectors.toList()));

//[5,4]

System.out.println(Arrays.asList(5, 4, 3, 2, 1).stream().limit(2).collect(Collectors.toList()));

//对元素进行排序,强大之处在于可以对Stream类进行map,filter,limit,skip,distinct之后在进行排序,提高效率。

//返回1、2、3

System.out.println(Arrays.asList(5, 4, 3, 2, 1).stream().skip(2).sorted(Integer::compare).collect(Collectors.toList()));

}

}

 

以上是 java8函数式编程 的全部内容, 来源链接: utcz.com/z/517700.html

回到顶部