2019年07月17日(星期三)  农历:己亥年六月十五

作者:三年。分类: JAVA

lambda表达式

语法

最常用的:

Runnable runnable = () -> System.out.println("Hello!");

Thread t = new Thread(runnable);

t.start();

t.join();

你还可以这么写:

Thread t = new Thread(() -> System.out.println("Hello!"));

t.start();

t.join();

带有参数的呢?

Comparator<String> stringComparator = (s1, s2) -> s1.compareTo(s2);

扩展成一个完整的表达式:

Comparator<String> stringComparator = (String s1, String s2) -> {

System.out.println("Comparing…");

return s1.compareTo(s2);

};

函数式接口

Lambda表达式使得你可以更紧凑地表达出单方法类。单一方法类也被称作函数式接口,它可以通过

@FunctionalInterface来进行注解:

@FunctionalInterface

public interface MyFunctionalInterface<T> {

boolean test(T t);

}

// Usage

MyFunctionalInterface<String> l = s -> s.startsWith("A");

方法引用

方法引用就是更紧凑,易懂的Lambda表达式,它适用于那些已经有名字的方法。来看一个简单的例子:

public class Sample {

public static void main(String[] args) {

Runnable runnable = Sample::run;

}

private static void run() {

System.out.println("Hello!");

}

}

还有一个:

public static void main(String[] args) {

Sample sample = new Sample();

Comparator<String> stringLengthComparator = sample::compareLength;

}

private int compareLength(String s1, String s2) {

return s1.length() - s2.length();

}

Stream API基础

stream是一个元素序列,它支持串行及并行的操作。

遍历列表

List<String> list = Arrays.asList("one", "two", "three", "four", "five", "six");

list.stream()

.forEach(s -> System.out.println(s));

过滤

Predicate<String> lowerThanOrEqualToFour = s -> s.length() <= 4;

Predicate<String> greaterThanOrEqualToThree = s -> s.length() >= 3;

list.stream()

.filter(lowerThanOrEqualToFour.and(greaterThanOrEqualToThree))

.forEach(s -> System.out.println(s));

排序

Predicate<String> lowerThanOrEqualToFour = s -> s.length() <= 4;

Predicate<String> greaterThanOrEqualToThree = s -> s.length() >= 3;

Comparator<String> byLastLetter = (s1, s2) -> s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1);

Comparator<String> byLength = (s1, s2) -> s1.length() - s2.length();

list.stream()

.filter(lowerThanOrEqualToFour.and(greaterThanOrEqualToThree))

.sorted(byLastLetter.thenComparing(byLength))

.forEach(s -> System.out.println(s));

大小限制

Predicate<String> lowerThanOrEqualToFour = s -> s.length() <= 4;

Predicate<String> greaterThanOrEqualToThree = s -> s.length() >= 3;

Comparator<String> byLastLetter = (s1, s2) -> s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1);

Comparator<String> byLength = (s1, s2) -> s1.length() - s2.length();

list.stream()

.filter(lowerThanOrEqualToFour.and(greaterThanOrEqualToThree))

.sorted(byLastLetter.thenComparing(byLength))

.limit(4)

.forEach(s -> System.out.println(s));


集合转化成列表

Predicate<String> lowerThanOrEqualToFour = s -> s.length() <= 4;

Predicate<String> greaterThanOrEqualToThree = s -> s.length() >= 3;

Comparator<String> byLastLetter = (s1, s2) -> s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1);

Comparator<String> byLength = (s1, s2) -> s1.length() - s2.length();

List<String> result = list.stream()

.filter(lowerThanOrEqualToFour.and(greaterThanOrEqualToThree))

.sorted(byLastLetter.thenComparing(byLength))

.limit(4)

.collect(Collectors.toList());

并行处理

用它来遍历文件列表则再常见不过了:

public static void main(String[] args) {

File[] files = new File("c:/windows")。listFiles();

Stream.of(files)

.parallel()

.forEach(Sample::process);

}

private static void process(File file) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

System.out.println("Processing -> " + file);

}

注意上面给出这个示例的同时,也暴露了并行处理的一些缺点。

Stream API进阶

映射

遍历文件后返回一个FileSize 对象:

class FileSize {

private final File file;

private final Long size;

FileSize(File file, Long size) {

this.file = file;

this.size = size;

}

File getFile() {

return file;

}

Long getSize() {

return size;

}

String getName() {

return getFile()。getName();

}

String getFirstLetter() {

return getName()。substring(0, 1);

}

@Override

public String toString() {

return Objects.toStringHelper(this)

.add("file", file)

.add("size", size)

.toString();

}

}

最终进行映射的代码:

File[] files = new File("c:/windows")。listFiles();

List<FileSize> result = Stream.of(files)

.map(FileSize::new)

.collect(Collectors.toList());

分组:

按文件名的第一个字母将FileSize对象分组

Map<String, List<FileSize》 result = Stream.of(files)

.map(FileSize::new)

.collect(Collectors.groupingBy(FileSize::getFirstLetter));

Reduce

找出文件夹下的最大最小文件:

Optional<FileSize> filesize = Stream.of(files)

.map(FileSize::new)

.reduce((fs1, fs2) -> fs1.getSize() > fs2.getSize() ? fs1 : fs2);

如果你不需要FileSize对象,只需要一个数值的话:

OptionalLong max = Stream.of(files)

.map(FileSize::new)

.mapToLong(fs -> fs.getSize())

.max();

温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,谢谢合作!

已有 0/1509 人参与

发表评论:



手Q扫描加入Java初学者群