java 8引入了Lambda表达式, 用以简化单抽象方法接口的实现
参数类型不需要申明, 参数类型自动推断
单抽象方法接口被称为函数式接口,标注为@FunctionalInterface
java的单方法接口: ComparatorRunnableCallable例子:
import java.util.Arrays; import java.util.Comparator; public class LambdaSample { public static void main(String[] args) throws Exception { String[] words = "Improving code with Lambda expressions in Java".split(" "); // Arrays.sort(words, new Comparator<String>() { // @Override // public int compare(String s1, String s2) { // // 忽略大小写排序: // return s1.toLowerCase().compareTo(s2.toLowerCase()); // } // }); Arrays.sort(words, (s1, s2) -> { return s1.toLowerCase().compareTo(s2.toLowerCase()); }); System.out.println(Arrays.toString(words)); } }s1, s2: 传入的参数
->{}: 方法过程
Runnable() 练习:
public class LambdaPractice { public static void main(String[] args) throws Exception { // TODO: 将Runnable改为lambda表达式: // Thread t = new Thread(new Runnable() { // @Override // public void run() { // System.out.println("start new thread..."); // } // }); // t.start(); // t.join(); Thread t = new Thread(() -> { System.out.println("start new thread"); }); t.start(); t.join(); } }jdk8中使用了::的用法。就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下,双冒号运算就是Java中的[方法引用],[方法引用]的格式是:
类名::方法名注意此处没有()。
代码示例:
import java.util.Arrays; class SortedBy { static int name(String s1, String s2) { return s1.compareTo(s2); } static int nameIgnoreCase(String s1, String s2) { return s1.toLowerCase().compareTo(s2.toLowerCase()); } static int length(String s1, String s2) { int n1 = s1.length(); int n2 = s2.length(); if (n1 == n2) { return s1.compareTo(s2); } return n1 < n2 ? -1 : 1; } } public class LambdaSort { public static void main(String[] args) throws Exception { String[] array = "Java Apple lambda functional OOP".split(" "); Arrays.sort(array, SortedBy::name); System.out.println(Arrays.toString(array)); } } 匿名类匿名类,就是没有名称的类,其名称由Java编译器给出,一般是形如:外部类名称+$+匿名类顺序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有构造器。
匿名类就是利用父类的构造函数和自身类体构造成一个类。
格式: new 父类(){子类内容}
Out out = new Out() { void show() { System.out.printIn("run in Inner"); } }Java8中引入了全新的Stream API, 在java.uti.stream包中
Stream API的特点:
Stream API提供了一套新的流式处理的抽象序列Stream API支持函数式变成/链式操作Stream 可以便是无限序列, 并且大多数情况下是惰性计算的stream API 不同于java.io中的InputStream和OutputStream:
java.ioJava.util.stream存储顺序读写的byte/char顺序输出的任意java对象用途序列化至文件/网络内存计算/业务逻辑stream API不同于java.util.List:
Jav.util.Listjava.util.stream元素已分配并存储在内存为分配, 实时计算用途操作一组已存在的java对象惰性计算 惰性计算 Stream<BigInteger> naturals = createNaturalStrem(); //不计算 Stream<BigInteger> s2 = naturals.map((n) -> n.multiply(n)); // 不计算 Stream<BigInteger> s3 = s2.limit(100); // 不计算 s3.forEach(System.out::printLn); // 计算例子:
package javatest; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; import java.util.stream.IntStream; import java.util.stream.Stream; /** * @ClassName TestB * @Description TODO * @Author lingxiangxiang * @Date 11:37 AM * @Version 1.0 **/ public class TestB { public static void main(String[] args) { String[] a = new String[]{"a", "b", "c", "d"}; int[] b = new int[]{1, 2, 3, 4, 5}; List<Integer> l1 = Arrays.asList(1, 2, 3, 4, 5); // 1. 通过Stream.of来创建 Stream<Integer> s1 = Stream.of(1, 2, 3, 4, 5); // 2. 通过数组来创建 Stream<String> s2 = Arrays.stream(a); // Stream<Integer> s3 = Arrays.stream(b); // 这样的方法时错误的 IntStream s4 = Arrays.stream(b); // 3. 通过Collection来创建 Stream<Integer> s5 = l1.stream(); // 4. 通过Supplier来创建 Stream<BigInteger> s6 = Stream.generate(new NaturalSupplier()); s1.forEach(System.out::println); s2.forEach(System.out::println); s4.forEach(System.out::println); s5.forEach(System.out::println); // limit的限定个数 s6.limit(10).forEach(System.out::println); } } class NaturalSupplier implements Supplier<BigInteger> { BigInteger next = BigInteger.ZERO; @Override public BigInteger get() { next = next.add(BigInteger.ONE); return next; } }map()方法: 将一个Stream的每个元素映射成另外一个元素并生成一个新的Stream, 可以将一个元素转换成另外一种元素类型
// 例子1 import java.util.Arrays; import java.util.stream.Stream; public class StreamMapSample { public static void main(String[] args) throws Exception { String[] array = "Stream API supports functional-style operations".split(" "); Stream<String> stream = Arrays.stream(array); stream.map(String::toUpperCase).forEach(System.out::println); } } // 例子2 import java.util.Arrays; import java.util.stream.Stream; class Person { String name; char gender; public Person(String name, char gender) { this.name = name; this.gender = gender; } public String toString() { return "Persion(" + name + ", " + gender + ")"; } } public class StreamMapSample2 { public static void main(String[] args) throws Exception { String[] inputs = { "Bob,M", "Alice,F", "Time,M", "Lily,F" }; Stream<String> names = Arrays.stream(inputs); Stream<Person> persons = names.map((s) -> { int n = s.indexOf(','); String name = s.substring(0, n); char gender = s.charAt(n + 1); return new Person(name, gender); }); persons.forEach(System.out::println); } }将一个Stream的每个元素进行测试,通过测试的元素被过滤后生成一个新的Stream, 用于排除不满足条件的元素
// 例子1 import java.util.function.Supplier; import java.util.stream.Stream; class NaturalSupplier implements Supplier<Long> { long x = 0; public Long get() { x++; return x; } } public class StreamFilterSample { public static void main(String[] args) throws Exception { Stream<Long> natural = Stream.generate(new NaturalSupplier()); Stream<Long> odd = natural.filter((n) -> n % 2 == 1); odd.limit(20).forEach(System.out::println); } } // 例子2 import java.util.Arrays; import java.util.stream.Stream; public class StreamFilterSample2 { public static void main(String[] args) throws Exception { String[] array = { "Java", " Python ", " ", null, "\n\n", " Ruby " }; Stream<String> normalized = Arrays.stream(array).filter(s -> s != null && !s.trim().isEmpty()) .map(s -> s.trim()); normalized.forEach(System.out::println); } }reduce()方法:
将一个Stream的每个元素依次作用于BiFunction,并将结果合并reduce是聚合方法聚合方法会立刻对Stream进行运算 public class StreamReduceSample { public static void main(String[] args) throws Exception { int r = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce((acc, x) -> acc * x).get(); System.out.println(r); System.out.println(1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9); } }forEach 和 pre-java8 的对比
// Java 8 roster.stream() .filter(p -> p.getGender() == Person.Sex.MALE) .forEach(p -> System.out.println(p.getName())); // Pre-Java 8 for (Person p : roster) { if (p.getGender() == Person.Sex.MALE) { System.out.println(p.getName()); } }java.util.stream.Stream提供了许多实用的功能:
转换操作:map, filter, sorted, distinct(去重)
合并操作:concat, flatMap
并行处理:parallel
聚合操作:reduce, count, max, min, sum, average
其他操作:allMatch, anyMatch, forEach
Stream转换为集合/数组类型:toArray, collect
limit(10): 取10个
skip(3): 忽律前三个
s5.sorted(Comparator.reverseOrder()).forEach(System.out::println);转载于:https://www.cnblogs.com/lingshang/p/10956640.html
相关资源:Java8中Lambda表达式使用和Stream API详解