面向对象思想需要关注对象做什么,函数式编程主要关注对数据的处理
Lambda是JDK8中的一个语法糖,可以对某些匿名内部类的写法进行简化。它是函数式编程的一个重要体现,让我们可以不用关注是什么对象,而是更关注对数据进行了什么操作。
函数式接口:指的是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,这样的接口可以隐式转换为 Lambda 表达式
可推导可省略
(参数列表)->{代码}
例一
new Thread(new Runnable(){
@override
public void run() {
System.out.println("balabala");
}
}).start();
改为Lambda表达式
new Thread(()->{
System.out.println("balabala");
}).start();
例二
public static <R> R typeConver(Function<String, R> function) {
String str = "123";
R result = function.apply(str);
return result;
}
改为Lambda表达式第一步
Integer result = typeConver(new Function<String, Interger>(){
@Override
public Interger apply(String s){
return Integer.valueOf(s);
}
});
System.out.println(result);
第二步
Integer result = typeConver(s -> Integer.valueOf(s));
System.out.println(result);
Lambda表达式可以引用类成员和局部变量,但是会将这些变量隐式的转化成final
String separator = ",";
Arrays.asList( "a", "b", "c" ).forEach(
( String e ) -> System.out.print( e + separator ) );
final String separator = ",";
Arrays.asList( "a", "b", "c" ).forEach(
( String e ) -> System.out.print( e + separator ) );
两者等价。
同时,Lambda 表达式的局部变量可以不用声明为final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
int num = 1;
Arrays.asList(1,2,3,4).forEach(e -> System.out.println(num + e));
num =2;
//报错信息:Local variable num defined in an enclosing scope must be final or effectively final
int num = 1;
Arrays.asList(1,2,3,4).forEach(num -> System.out.println(num));
//报错信息:Variable 'num' is already defined in the scope
Stream使用的是函数式编程模式,可以被用来对集合或数组进行链状流式的操作。
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Author {
private Long id;
private String name;
private String intro;
private Integer age;
private List<Book> books;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Book {
private Long id;
private String name;
private String category;
private Integer score;
private String intro;
}
public static List<Author> getAuthors() {
List<Book> books1 = new LinkedList<>();
List<Book> books2 = new LinkedList<>();
List<Book> books3 = new LinkedList<>();
books1.add(new Book(11L,"book11","category11",18, "intro1"));
books1.add(new Book(12L,"book12","category12",17, "intro12"));
books2.add(new Book(21L,"book21","category21",27, "intro2"));
books2.add(new Book(22L,"book22","category22",28, "intro21"));
books2.add(new Book(23L,"book23","category23",29, "intro23"));
books3.add(new Book(31L,"book31","category31",39, "intro31"));
books3.add(new Book(32L,"book32","category32",32, "intro32"));
books3.add(new Book(33L,"book33","category33",33, "intro33"));
books3.add(new Book(34L,"book34","category34",34, "intro34"));
Author author1 = new Author(1L,"author1","intro1",11, books1);
Author author2 = new Author(2L,"author2","intro2",22, books2);
Author author3 = new Author(3L,"author3","intro3",33, books3);
List<Author> authors = new LinkedList<>();
authors.add(author1);
authors.add(author2);
authors.add(author3);
return authors;
}
public static void main(String[] args) {
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
stream
.distinct()
.filter(author -> author.getAge()<=22)
.forEach(System.out::println);
System.out.println("ccccc"+authors);
stream.forEach(System.out::println);
}

NOTE:
学习过程中一个好用的工具

可以查看stream每一步对数据的处理。

单列集合
对象.Stream()即可
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
数组
Arrays.stream(arr)或者是用Stream.of来创建
Integer[] arr = [1,2,3,4,5];
Stream<Interger> stream = Arrays.stream(arr);
Stream<Interger> stream2 = Stream.of(arr);
双列集合\
先转化为单列形式,再转化
Map<String, Integer> map = new HashMap<>();
map.put("age1",11);
map.put("age2",22);
map.put("age3",33);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Stream<Map.Entry<String, Integer>> stream = entrySet.stream();