一. 简介
1. 在语言层面上修改现有的Java,增加Lambda表达式,让代码在多核CPU上高效运行;
2. 面向对象编程是对数据进行抽象,函数式编程是对行为进行抽象;
3. 一个简单的例子
botton.addActionListener(new ActionListener() { public void actionPerformed() { System.out.println("button clicked"); } });
匿名内部类的目的是为了方便将代码作为数据传递;
button.addActionListener(event -> System.out.println("botton clicked"));
和传入一个实现某接口的对象不同,我们传入了一段代码块,event是参数名,无需指定类型,javac根据程序的上下文可以推断出参数的类型,->将参数和Lambda表达式的主体分开,主体是用户点击按钮时会运行的一些代码;
4. Lambda表达式的几种不同形式
Runnable noArguments = () -> System.out.print("Hello world"); // 使用空括号表示没有参数 ActionListener oneArgument = event -> System.out.print("button clicked"); // 有且只有一个参数可以省略参数的括号 Runnable multiStatement = () -> { // 表达式主体可以是一段代码块 System.out.print("Hello"); System.out.println("world"); } BinaryOperator<Long> add = (x, y) -> x + y; // 包含多个参数;也可以显示声明参数类型
5. 引用值而不是变量
可以引用非final变量,但是该变量在既成事实上必须是final;
如果试图给变量多次赋值,然后在Lambda表达式中引用它,编译器会报错:local variables referenced from a Lambda expression must be final or effectively final;
// name是一个既成事实上的final变量 String name = getUserName(); button.addActionListener(event -> System.out.println("hi" + name)); // 无法通过编译 String name = getUserName(); name = formatUserName(name); button.addActionListener(event -> System.out.println("hi" + name));
6. 函数接口
函数接口是只有一个抽象方法的接口,用作Lambda表达式;
一些重要的函数接口:
Predicate<T> 参数T,返回类型boolean;
Consumer<T> 参数T,返回类型void;
Function<T, R> 参数T,返回类型R;
Supplier<T> 参数None,返回类型T;
UnaryOperator<T> 参数T,返回类型T;
BinaryOperator<T> 参数(T, T),返回类型T;
7. 方法引用
artist -> artist.getName() 可以写成 Artist::getName;
标准语法为Classname::methodName;
二. 流
常用的流操作
List<String> collected = Stream.of("a", "b", "c").collect(Collectors.toList()); List<String> collected = Stream.of("a", "b", "c").map(string -> string.toUpperCase()).collect(Collectors.toList()); List<String> collected = Stream.of("a", "1abc", "abc1").filter(value -> isDigit(value.charAt(0))).collect(toList()); List<Integer> together = Stream.of(asList(1,2), asList(3,4)).flatMap(numbers -> numbers.stream()).collect(toList()); Track shortestTrack = tracks.stream().min(Comparator.comparing(track -> track.getLength())).get(); int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
List<Integer> sameOrder = numbers.stream().sorted().collect(toList());
stream.collect(toCollection(TreeSet::new));
artists.collect(maxBy(comparing(getCount)));
albums.stream().collect(averagingInt(album -> album.getTrackList().size()));
artists.collect(partitioningBy(artist -> artist.isSolo()));
albums.collect(groupingBy(album -> album.getMainMusician()));
artists.stream().map(Artist::getName).collect(Collectors.joining(",", "[", "]"));
albums.collect(groupingBy(Album::getMainMusician, mapping(Album::getName, toList())));
artistCache.computeIfAbsent(name, this::readArtistFromDB);
albumsByArtist.forEach((artist, albums) -> {countOfAlbums.put(artist, albums.size())});
album.getMusicians().peek(nation -> System.out.print("Found nationality:" + nation)).collect(Collectors.<String>toSet());
三. 数据并行化
albums.parallelStream().flatMap(Album::getTracks).mapToInt(Track::getLength).sum();
数组上的并行化操作:
parallelPrefix();parallelSetAll();parallelSort();
原文:https://www.cnblogs.com/bbbbs/p/12575701.html