jdk程序员Java

Java 8 相关整理

2018-05-23  本文已影响160人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

1. Lambda 表达式

(parameters) -> expression
(parameters) -> { statements; }

1.1 表达式重要特征

public class Test {

    public static void main(String[] args) {
        Operation subtractionA = (int a, int b) -> a - b;
        Operation subtractionB = (a, b) -> a - b;
    }

    interface Operation {
        int operation(int a, int b);
    }
}
public class Test {

    public static void main(String[] args) {

        OperationA subtractionA = (int a, int b) -> a - b;
        OperationB subtractionB = a -> a * 2;

    }

    interface OperationA {
        int operation(int a, int b);
    }

    interface OperationB {
        int operation(int a);
    }
}
public class Test {

    public static void main(String[] args) {

        OperationA subtractionA = (int a, int b) -> {
            return a - b;
        };

    }

    interface OperationA {
        int operation(int a, int b);
    }
}

1.2 变量作用域

public class Test {

    private static int c = 1;

    public static void main(String[] args) {

        Operation subtractionA = (a, b) -> a + b + c;

    }

    interface Operation {
        int operation(int a, int b);
    }
}

2. 方法引用

public class Test {

    public static void main(String[] args) {
        Operation operation = Operation.create(Operation::new);
    }

    static class Operation {

        public static Operation create(final Supplier<Operation> supplier) {
            return supplier.get();
        }
    }
}
public class Test {

    public static void main(String[] args) {
        List<Operation> operations = Arrays.asList(new Operation());
        operations.forEach(Operation::print);
    }

    static class Operation {

        public static void print(final Operation operation) {
            System.out.print(operation.toString());
        }
    }
}
public class Test {

    public static void main(String[] args) {
        final Operation operation = new Operation();
        List<Operation> operations = Arrays.asList(operation);
        operations.forEach(System.out::print);
    }

    static class Operation {
    }

}
public class Test {

    public static void main(String[] args) {
        final Operation operation = new Operation();
        List<Operation> operations = Arrays.asList(operation);
        operations.forEach(operation::print);
    }

    static class Operation {

        public void print(final Operation Operation) {
            System.out.print(Operation.toString());
        }
    }
}

3. 函数式接口

序号 接口 描述
1 BiConsumer<T,U> 代表了一个接受两个输入参数的操作,并且不返回任何结果。
2 BiFunction<T,U,R> 代表了一个接受两个输入参数的方法,并且返回一个结果。
3 BinaryOperator<T> 代表了一个作用于两个同类型操作符的操作,并且返回了操作符同类型的结果。
4 BiPredicate<T,U> 代表了一个两个参数的 boolean 值方法。
5 BooleanSupplier 代表了 boolean 值结果的提供方。
6 Consumer<T> 代表了接受一个输入参数并且无返回的操作。
7 DoubleBinaryOperator 代表了作用于两个 double 值操作符的操作,并且返回一个 double 值的结果。
8 DoubleConsumer 代表一个接受 double 值参数的操作,并且不返回结果。
9 DoubleFunction<R> 代表接受一个 double 值参数的方法,并且返回结果。
10 DoublePredicate<R> 代表一个拥有 double 值参数的 boolean 值方法。
11 DoubleSupplier 代表一个 double 值结构的提供方。
12 DoubleToIntFunction 接受一个 double 类型输入,返回一个 int 类型结果。
13 DoubleToLongFunction 接受一个 double 类型输入,返回一个 long 类型结果。
14 DoubleUnaryOperator 接受一个参数同为类型 double,返回值类型也为 double 。
15 Function<T,R> 接受一个输入参数,返回一个结果。
16 IntBinaryOperator 接受两个参数同为类型 int,返回值类型也为 int 。
17 IntConsumer 接受一个 int 类型的输入参数,无返回值 。
18 IntFunction<R> 接受一个 int 类型输入参数,返回一个结果 。
19 IntPredicate 接受一个 int 输入参数,返回一个 boolean 的结果。
20 IntSupplier 无参数,返回一个 int 类型结果。
21 IntToDoubleFunction 接受一个 int 类型输入,返回一个 double 类型结果 。
22 IntToLongFunction 接受一个 int 类型输入,返回一个 long 类型结果。
23 IntUnaryOperator 接受一个参数同为类型 int,返回值类型也为 int 。
24 LongBinaryOperator 接受两个参数同为类型 long,返回值类型也为 long。
25 LongConsumer 接受一个 long 类型的输入参数,无返回值。
26 LongFunction<R> 接受一个 long 类型输入参数,返回一个结果。
27 LongPredicate 接受一个 long 输入参数,返回一个 boolean 类型结果。
28 LongSupplier 无参数,返回一个结果 long 类型的值。
29 LongToDoubleFunction 接受一个 long 类型输入,返回一个 double 类型结果。
30 LongToIntFunction 接受一个 long 类型输入,返回一个int类型结果。
31 LongUnaryOperator 接受一个参数同为类型 long,返回值类型也为 long。
32 ObjDoubleConsumer<T> 接受一个 object 类型和一个 double 类型的输入参数,无返回值。
33 ObjIntConsumer<T> 接受一个 object 类型和一个 int 类型的输入参数,无返回值。
34 ObjLongConsumer<T> 接受一个 object 类型和一个 long 类型的输入参数,无返回值。
35 Predicate<T> 接受一个输入参数,返回一个 boolean 结果。
36 Supplier<T> 无参数,返回一个结果。
37 ToDoubleBiFunction<T,U> 接受两个输入参数,返回一个 double 类型结果。
38 ToDoubleFunction<T> 接受一个输入参数,返回一个 double 类型结果。
39 ToIntBiFunction<T,U> 接受两个输入参数,返回一个 int 类型结果。
40 ToIntFunction<T> 接受一个输入参数,返回一个 int 类型结果。
41 ToLongBiFunction<T,U> 接受两个输入参数,返回一个 long 类型结果。
42 ToLongFunction<T> 接受一个输入参数,返回一个 long 类型结果。
43 UnaryOperator<T> 接受一个参数为类型 T,返回值类型也为 T。
public class Test {

    public static void main(String[] args) {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        eval(list, n -> true);
    }

    public static void eval(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {

            if (predicate.test(n)) {
                System.out.println(n);
            }
        }
    }
}

4. 默认方法

public interface IOperation {
   default void print(){
      System.out.println("");
   }
}

4.1 多个默认方法

public interface IOperationA {
   default void print(){
      System.out.println("");
   }
}
 
public interface IOperationB {
   default void print(){
      System.out.println("");
   }
}
public class Operation implements IOperationA, IOperationB  {
   default void print(){
      System.out.println("");
   }
}
public class Operation implements IOperationA, IOperationB  {
   public void print(){
      IOperationA.super.print();
   }
}

4.2 静态默认方法

public interface Operation {
   default void printA(){
      System.out.println("A");
   }
    // 静态方法
   static void printB(){
      System.out.println("B");
   }
}

5. Stream

List<Integer> transactionsIds = widgets.stream().filter(b -> b.getColor() == RED).sorted((x,y) -> x.getWeight() - y.getWeight()).mapToInt(Widget::getWeight).sum();

5.1 生成流

5.1.1 静态工厂方法。

5.1.1.1 of

方法 说明
- of(T... values) 返回含有多个 T 元素的 Stream
- of(T t) 返回含有一个 T 元素的 Stream
Stream<Integer> integerStream = Stream.of(1, 2, 3);
Stream<String> stringStream = Stream.of("A");

5.1.1.2 generator

方法 说明
- generate(Supplier<T> s) 返回一个无限长度的 Stream
Stream.generate(java.lang.Math::random);

一般无限长度的 Stream 会与 filter、limit 等配合使用,否则 Stream 会无限制的执行下去。

5.1.1.3 iterate

Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);

5.1.1.4 empty

Stream.empty();

5.1.2 Collection 接口和数组的默认方法

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).collect(Collectors.toList());
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// 获取对应的平方数
List<Integer> squaresList = numbers.parallelStream().map( i -> i*i).collect(Collectors.toList());
int id[] = new int[]{1, 2, 3, 4};
Arrays.stream(id).forEach(System.out::println);

5.1.3 其他

5.2 中间操作(Intermediate)

5.2.1 concat

Stream.concat(Stream.of(1, 2, 3), Stream.of(4, 5)).forEach(System.out::println);

5.2.2 distinct

Stream.of(1, 2, 3, 1, 2, 3).distinct().forEach(System.out::println);

5.2.3 filter

// 获取空字符串的数量
Stream.of("1", "2", "3", "4", "", "", "7", "", "").filter(string -> string.isEmpty()).count();

5.2.4 map

// 获取对应的平方数
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).map(i -> i * i).collect(Collectors.toList());

5.2.5 flatMap

Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).flatMap(i -> i * i).collect(Collectors.toList());

5.2.6 peek

Stream.of(1, 2, 3).peek(x -> System.out.print(x));

5.2.7 skip

Stream.of(1, 2, 3,4,5) .skip(2) .forEach(System.out::println); 

5.2.8 sorted

Stream.of(5, 4, 3, 2, 1).sorted().forEach(System.out::println);

5.3 最终操作(Terminal)

5.3.1 collect

5.3.1.1 转换成其他集合

List<Integer> collectList = Stream.of(1, 2, 3, 4).collect(Collectors.toList());
Set<Integer> collectSet = Stream.of(1, 2, 3, 4).collect(Collectors.toSet());
TreeSet<Integer> collectSet = Stream.of(1, 2, 3, 4).collect(Collectors.toCollection(TreeSet::new));
public Map<Long, String> getIdNameMap(List<Account> accounts) {
    return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getUsername));
}

5.3.1.2 转成值

方法 说明
averagingDouble 求平均值,Stream 的元素类型为 double。
averagingInt 求平均值,Stream 的元素类型为 int。
averagingLong 求平均值,Stream 的元素类型为 long。
counting Stream 的元素个数
maxBy 在指定条件下的,Stream 的最大元素。
minBy 在指定条件下的,Stream 的最小元素。
reducing reduce 操作。
summarizingDouble 统计 Stream 的数据(double)状态,其中包括 count,min,max,sum 和平均。
summarizingInt 统计 Stream 的数据(int)状态,其中包括 count,min,max,sum 和平均。
summarizingLong 统计 Stream 的数据(long)状态,其中包括 count,min,max,sum 和平均。
summingDouble 求和,Stream 的元素类型为 double。
summingInt 求和,Stream 的元素类型为 int。
summingLong 求和,Stream 的元素类型为 long。
Optional<Integer> collectMaxBy = Stream.of(1, 2, 3, 4).collect(Collectors.maxBy(Comparator.comparingInt(o -> o)));

5.3.1.3 分割数据块

Map<Boolean, List<Integer>> collectParti = Stream.of(1, 2, 3, 4).collect(Collectors.partitioningBy(it -> it % 2 == 0));

5.3.1.4 数据分组

Map<Boolean, List<Integer>> collectGroup= Stream.of(1, 2, 3, 4).collect(Collectors.groupingBy(it -> it > 3));

5.3.1.5 字符串

Stream.of("1", "2", "3", "4").collect(Collectors.joining(",", "[", "]"));

5.3.1.6 组合 Collector

Map<Boolean, Long> partiCount = Stream.of(1, 2, 3, 4, 5).collect(Collectors.partitioningBy(it -> it.intValue() % 2 == 0, Collectors.counting()));
System.out.println("partiCount: " + partiCount);
// 打印结果
// partiCount: {false=3, true=2}

5.3.2 count

Stream.of(1, 2, 3, 4, 5).count();

5.3.3 forEach

Stream.of(1, 2, 3).forEach(System.out::println);

5.3.4 forEachOrdered

Stream.of(1, 2, 3).forEachOrdered(System.out::println);

5.3.5 max

Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).max((o1, o2) -> o2 - o1);

5.3.6 min

Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).max((o1, o2) -> o1 - o2);

5.4 非短路操作(Short-circuiting)

5.4.1 allMatch

Stream.of(1, 2, 3, 4).allMatch(integer -> integer > 2);

5.4.2 anyMatch

Stream.of(1, 2, 3, 4).anyMatch(integer -> integer > 3);

5.4.3 findAny

Stream.of(1, 2, 3, 4).findAny();

5.4.4 findFirst

Stream.of(1, 2, 3, 4).findFirst();

5.4.5 limit

Stream.of(1, 2, 3,4,5).limit(2).forEach(System.out::println);

5.4.6 noneMatch

Stream.of(1, 2, 3, 4, 5).noneMatch(integer -> integer > 10);

5.4.7 reduce

Stream.of(1, 2, 3, 4)
        .reduce((acc, item) -> {
            acc += item;
            return acc;
        });

6. Optional

序号 方法 描述
1 static <T> Optional<T> empty() 返回空的 Optional 实例。
2 boolean equals(Object obj) 判断其他对象是否等于 Optional。
3 Optional<T> filter(Predicate<? super <T> predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个 Optional 用以描述这个值,否则返回一个空的 Optional。
4 <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper) 如果值存在,返回基于 Optional 包含的映射方法的值,否则返回一个空的 Optional。
5 T get() 如果在这个 Optional 中包含这个值,返回值,否则抛出异常:NoSuchElementException
6 int hashCode() 返回存在值的哈希码,如果值不存在 返回 0。
7 void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情。
8 boolean isPresent() 如果值存在则方法会返回 true,否则返回 false。
9 <U>Optional<U> map(Function<? super T,? extends U> mapper) 如果存在该值,提供的映射方法,如果返回非 null,返回一个 Optional 描述结果。
10 static <T> Optional<T> of(T value) 返回一个指定非 null 值的 Optional。
11 static <T> Optional<T> ofNullable(T value) 如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
12 T orElse(T other) 如果存在该值,返回值, 否则返回 other。
13 T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
14 <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
15 String toString() 返回一个 Optional 的非空字符串,用来调试。
Optional<Integer> a = Optional.ofNullable(value);

7. 日期时间

// 获取当前的日期时间
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前时间: " + currentTime);
        
LocalDate date1 = currentTime.toLocalDate();
System.out.println("date1: " + date1);
        
Month month = currentTime.getMonth();
int day = currentTime.getDayOfMonth();
int seconds = currentTime.getSecond();
        
System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
        
LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
System.out.println("date2: " + date2);
        
// 12 december 2014
LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
System.out.println("date3: " + date3);
        
// 22 小时 15 分钟
LocalTime date4 = LocalTime.of(22, 15);
System.out.println("date4: " + date4);
        
// 解析字符串
LocalTime date5 = LocalTime.parse("20:15:30");
System.out.println("date5: " + date5);
// 获取当前时间日期
ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
System.out.println("date1: " + date1);
        
ZoneId id = ZoneId.of("Europe/Paris");
System.out.println("ZoneId: " + id);
        
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("当期时区: " + currentZone);

8. Base64

序号 内嵌类 描述
1 static class Base64.Decoder 该类实现一个解码器用于,使用 Base64 编码来解码字节数据。
2 static class Base64.Encoder 该类实现一个编码器,使用 Base64 编码来编码字节数据。
序号 方法名 描述
1 static Base64.Decoder getDecoder() 返回一个 Base64.Decoder ,解码使用基本型 base64 编码方案。
2 static Base64.Encoder getEncoder() 返回一个 Base64.Encoder ,编码使用基本型 base64 编码方案。
3 static Base64.Decoder getMimeDecoder() 返回一个 Base64.Decoder ,解码使用 MIME 型 base64 编码方案。
4 static Base64.Encoder getMimeEncoder() 返回一个 Base64.Encoder ,编码使用 MIME 型 base64 编码方案。
5 static Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator) 返回一个 Base64.Encoder ,编码使用 MIME 型 base64 编码方案,可以通过参数指定每行的长度及行的分隔符。
6 static Base64.Decoder getUrlDecoder() 返回一个 Base64.Decoder ,解码使用 URL 和文件名安全型 base64 编码方案。
7 static Base64.Encoder getUrlEncoder() 返回一个 Base64.Encoder ,编码使用 URL 和文件名安全型 base64 编码方案。
// 使用基本编码
String base64encodedString = Base64.getEncoder().encodeToString("runoob?java8".getBytes("utf-8"));
System.out.println("Base64 字符串 (基本) :" + base64encodedString);
        
// 解码
byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
        
System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));
base64encodedString = Base64.getUrlEncoder().encodeToString("TutorialsPoint?java8".getBytes("utf-8"));
System.out.println("Base64 编码字符串 (URL) :" + base64encodedString);
        
StringBuilder stringBuilder = new StringBuilder();
        
for (int i = 0; i < 10; ++i) {
    stringBuilder.append(UUID.randomUUID().toString());
}
        
byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
System.out.println("Base64 编码字符串 (MIME) :" + mimeEncodedString);

9. Nashorn JavaScript

9.1 Java 中调用 JavaScript

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
        
String name = "Runoob";
Integer result = null;
      
try {
    nashorn.eval("print('" + name + "')");
    result = (Integer) nashorn.eval("10 + 2");
}catch(ScriptException e){
    System.out.println("执行脚本错误: "+ e.getMessage());
}
      
System.out.println(result.toString());

9.2 JavaScript 中调用 Java

var BigDecimal = Java.type('java.math.BigDecimal');

function calculate(amount, percentage) {

   var result = new BigDecimal(amount).multiply(
   new BigDecimal(percentage)).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
   
   return result.toPlainString();
}

var result = calculate(568000000000000000023,13.9);
print(result);

参考资料

Java 8 中的 Streams API 详解
Java 8 新特性

上一篇 下一篇

猜你喜欢

热点阅读