1. 接口中有默认的实现方法
interface Formula{ double calculate(int num); default double sqrt(int n){ // 实现类自动获得default标记的方法 return Math.sqrt(n); } } public class Java8 { public static void main(String[] args) { Formula formula = new Formula(){ @Override public double calculate(int n) { return sqrt(n * 100); } }; System.out.println(formula.calculate(4));//4*10开平方 = 20.0 System.out.println(formula.sqrt(900)); // 900开平方 = 30.0 } }
2.lambda 表达式-排序
public static void main(String[] args) { List<String> fruits = Arrays.asList("apple", "banana", "corn", "pear", "mango", "orange"); //1.传统排序 Collections.sort(fruits, new Comparator<String>() { @Override public int compare(String a, String b) { return b.compareTo(a); //后面b在前面a就是逆序 } }); System.out.println(fruits); //[pear, orange, mango, corn, banana, apple] 后面的排在前面 //2. lambda 排序 Collections.sort(fruits, (String a, String b) ->{return a.compareTo(b);}); System.out.println(fruits); //顺序[apple, banana, corn, mango, orange, pear] Collections.sort(fruits,(String a, String b) -> b.compareTo(a)); System.out.println(fruits); // 逆序[pear, orange, mango, corn, banana, apple] }
3. 函数式接口@FunctionalInterface: 接口中只能有一个抽象方法!可以有多个默认方法!
@FunctionalInterface public interface Converter<F, T> { T convert(F from); } //(from) ->Integer.valueOf(from)??? public static void main(String[] args) { Converter<String, Integer> converter = (from) ->Integer.valueOf(from); Integer converted = converter.convert("1234"); System.out.println(converted);//1234 }
4. 方法与构造方法的引用 ::
//4.1
@FunctionalInterface public interface Converter<F, T> { T convert(F from); } // Integer::valueOf??? public class Java8 { public static void main(String[] args) { Converter<String, Integer> converter = Integer::valueOf; Integer converted = converter.convert("123"); System.out.println(converted); //123 } }
//4.2 public class Person { String firstName; String lastName; Person(){} Person(String firstName, String lastName){ this.firstName = firstName; this.lastName = lastName; } } public interface PersonFactory<P extends Person> { // P 是泛型 P create(String firstName, String lastName); } public class Java8 { public static void main(String[] args) { PersonFactory<Person> personFactory = Person::new; Person coco = personFactory.create("coco","可可"); System.out.println(coco.firstName + ":" + coco.lastName); // coco:可可 } }
5. Lambda作用域
@FunctionalInterface public interface Converter<F, T> { T convert(F from); } // lambda对本地变量只有读操作, 对静态变量和对象属性有读写操作 public class Java8 { public static void main(String[] args) { int num = 1; // 加final也可以 Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num); String result = stringConverter.convert(301); System.out.println(result); //31 // num = 8; //被lambda表达式用过就具有final属性,不能更改它的value :如下则报错 // System.out.println(num); //Error:(13, 86) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量 } }
6.Optinal接口 防止NullPointerException异常的辅助类型,推荐不返回null而是返回Optional
public class Java8 { public static void main(String[] args) { Optional<String> optional = Optional.of("bam"); // Optional<String> optional = new Optional<String>(value); System.out.println(optional.isPresent()); // true return value != null; System.out.println(optional.get()); // bam value !=null ? value : throw new NoSuchElementException("No value present"); System.out.println(optional.orElse("fallback")); //bam value != null ? value : other optional.ifPresent((str) -> System.out.println(str.charAt(0))); //b if (value != null) consumer.accept(value); } }
7. Stream 接口
java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行执行或者并行执行。
public class Java8 {
public static void main(String[] args) {
List<String> stringCollection = new ArrayList<>();
stringCollection.add("aaa1");
stringCollection.add("bbb1");
stringCollection.add("ccc1");
stringCollection.add("ddd1");
stringCollection.add("aaa2");
stringCollection.add("bbb2");
stringCollection.add("ccc2");
stringCollection.add("ddd2");
stringCollection.stream().filter((str) ->str.startsWith("a")).forEach(System.out::println); // aaa1 aaa2
stringCollection.forEach(System.out :: println); //遍历数组方式1
stringCollection.stream().forEach(System.out :: println); //遍历数组方式2
//map 映射 map会将元素根据指定的Function接口来依次将元素转成另外的对象
stringCollection.stream()
.map(String :: toUpperCase)
.sorted((a, b) ->b.compareTo(a))
.forEach(System.out::println); //先大写后逆序排序, 原集合内容顺序不变
//match 匹配
boolean anyStartWithA = stringCollection.stream().anyMatch((s) ->s.startsWith("a"));
System.out.println(anyStartWithA); // true, 只要有一个匹配即为真
boolean allStartWithA = stringCollection.stream().allMatch((str) -> str.startsWith("a"));
System.out.println(allStartWithA); // false
boolean noneStartWithZ = stringCollection.stream().noneMatch((s) ->s.startsWith("z"));
System.out.println(noneStartWithZ); // true;
}
}
8. count计数, reduce规约, 并行stream
//计数 long startWithB = stringCollection.stream().filter((s) ->s.startsWith("b")).count(); System.out.println(startWithB); //reduce规约 最终操作,多个元素规约成一个元素通过Optional接口 Optional<String> reduced = stringCollection.stream().sorted().reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println); // 元素通过# 分隔开 // 并行 Stream int max = 1000000; List<String> values = new ArrayList<>(max); for(int i =0; i < max ; i++) { UUID uuid = UUID.randomUUID(); values.add(uuid.toString()); } long t1 = System.nanoTime(); System.out.println(t1); //98447121117166 long count = values.stream().sorted().count(); //一百万个数排序 System.out.println(count); long t2 = System.nanoTime(); long mills = TimeUnit.NANOSECONDS.toMillis(t2 - t1); System.out.println(mills); //905 long t3 = System.nanoTime(); System.out.println(t3); long count1 = values.parallelStream().sorted().count(); System.out.println(count1); long t4 = System.nanoTime(); long mills_diff = TimeUnit.NANOSECONDS.toMillis(t4 - t3); System.out.println(mills_diff); // 546