该博客文章包含基本Lambda表达式和Stream API示例的列表,我在2014年6月在Java用户组– Politechnica Gedanensis (格但斯克技术大学)和Goyello的实时编码演示中使用了这些示例。
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();
}
流API –基础
流是支持顺序和并行批量操作的一系列元素。
遍历列表
List<String> list = Arrays.asList("one", "two", "three", "four", "five", "six");list.stream().forEach(s -> System.out.println(s));
筛选
Java 8在接口中引入了默认方法。 它们在Stream API中非常方便:
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));
在上面的示例中,使用了默认方法and
java.util.function.Predicate
。 默认(和静态)方法是Java 8中接口的新增方法。
限制
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);
}
请注意,在显示示例时,我解释了并行处理流的一些已知缺点。
流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);}@Overridepublic 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));
降低
获取目录中最大/最小的文件:
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();
翻译自: https://www.javacodegeeks.com/2014/06/lambda-expressions-and-stream-api-basic-examples.html