3 java8新特性總結
阿新 • • 發佈:2018-05-20
應用 rst pan UC 括號 st2 array 創建 new
java8中重要的4個新特性:
- Lambda
- Stream
- Optional
- 日期時間API
一、Lambda
1 import java.util.Comparator; 2 import java.util.function.Consumer; 3 4 /** 5 * @author zhaojigang 6 * @date 2018/5/19 7 */ 8 public class LambdaTest { 9 /** 10 * Lambda 是一個匿名函數。 11 * 1、語法 12 * Lambda表達式引入了操作符為"->",該操作符將Lambda分為兩個部分:13 * 左側:指定了Lambda表達式需要的所有參數 14 * 右側:指定了Lambda體,即Lambda表達式要執行的功能。 15 * 16 * 2、示例 17 */ 18 public void testLambda() { 19 /** 20 * 語法格式一:無參,無返回值 21 */ 22 Runnable task = () -> System.out.println("hello lambda"); 23 /** 24 * 語法格式二:一個參數,無返回值25 * 註意:參數類型可以通過 26 */ 27 Consumer<String> consumer = str -> System.out.println(str); 28 /** 29 * 語法格式三:一個參數,有返回值 30 * 註意:當Lambda體只有一條語句時,省略大括號和return 31 */ 32 Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);33 } 34 35 /** 36 * 函數式接口:只包含一個抽象方法的接口。 37 * 1、可以通過Lambda表達式來創建該接口的對象 38 * 2、可以在任意函數式接口上使用@FunctionalInterface註解,這樣做可以檢查它是否是一個函數式接口 39 * 40 * Java內置了四大核心函數式接口: 41 * 1、Consumer<T>:void accept(T t),消費型接口 42 * 2、Supplier<T>:T get(),供給型接口 43 * 3、Function<T, R>:R apply(T t),函數型接口 44 * 4、Predicate<T>:boolean test(T t),斷言型接口 45 * 還有部分子接口。 46 */ 47 public void testFunctionalInterface() { 48 Consumer<String> consumer = str -> System.out.println(str); 49 } 50 }
二、Stream
1 import java.util.ArrayList; 2 import java.util.HashMap; 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Optional; 6 import java.util.OptionalLong; 7 import java.util.stream.LongStream; 8 9 /** 10 * @author zhaojigang 11 * @date 2018/5/19 12 */ 13 public class StreamTest { 14 15 static List<Integer> integerList = new ArrayList<Integer>() {{ 16 add(1); 17 add(2); 18 add(3); 19 add(4); 20 add(5); 21 add(5); 22 add(5); 23 }}; 24 25 static List<Integer> integerList2 = new ArrayList<Integer>() {{ 26 add(10); 27 add(20); 28 add(30); 29 }}; 30 31 static Map<String, List<Integer>> map1 = new HashMap<>(); 32 33 static { 34 map1.put("list1", integerList); 35 map1.put("list2", integerList2); 36 } 37 38 /** 39 * 分片與篩選 40 */ 41 public static void test1() { 42 integerList.stream() 43 .filter(x -> x > 2) // 3,4,5,5,5 44 .skip(2) //5,5,5 45 .limit(2) //5,5 短路:一旦獲取到2個元素後不再向後叠代 46 .distinct() //5 47 .forEach(System.out::println); 48 } 49 50 /** 51 * 映射 52 * map(Function f):接收一個函數作為參數,該函數會被應用到每個元 素上,並將其映射成一個新的元素 53 * flatMap(Function f):接收一個函數作為參數,將流中的每個值都換成另一個流,然後把所有流連接成一個流 54 */ 55 public static void test2() { 56 integerList.stream() 57 .map(x -> x + 10) 58 .forEach(System.out::println); 59 60 map1.values().stream() 61 .flatMap(x -> x.stream()) // x是每一個List,flatMap將每一個List的Stream合並起來 62 .forEach(System.out::println); 63 64 } 65 66 /** 67 * 排序 68 * sorted():產生一個新流,其中按自然順序排序(按照元素的Comparable接口) 69 * sorted(Comparator comp):產生一個新流,其中按比較器順序排序(按照自定義的Comparator) 70 */ 71 public static void test3() { 72 integerList.stream() 73 .sorted() 74 .forEach(System.out::println); 75 76 integerList.stream() 77 .sorted((x, y) -> { 78 if (x < y) { 79 return 1; 80 } else { 81 return -1; 82 } 83 }) 84 .forEach(System.out::println); 85 86 } 87 88 /** 89 * 查找與匹配 90 * allMatch(Predicate p):檢查是否匹配所有元素 91 * anyMatch(Predicate p):檢查是否至少匹配一個元素 92 * noneMatch(Predicate p):檢查是否沒有匹配所有元素 93 * findFirst():返回第一個元素 94 * findAny():返回當前流中的任意元素 95 * count():返回流中元素總數 96 * max(Comparator c):返回流中最大值 97 * min(Comparator c):返回流中最小值 98 */ 99 public static void test4() { 100 final boolean allMatch = integerList.stream().allMatch(x -> x > 4); 101 final boolean anyMatch = integerList.stream().anyMatch(x -> x > 4); 102 final boolean noneMatch = integerList.stream().noneMatch(x -> x > 4); 103 final Optional<Integer> first = integerList.stream().filter(x -> x > 3).findFirst(); 104 final Optional<Integer> any = integerList.stream().filter(x -> x > 3).findAny(); 105 final long count = integerList.stream().filter(x -> x > 4).count(); 106 final Optional<Integer> max = integerList.stream() 107 .max((x, y) -> { 108 if (x < y) { 109 return 1; 110 } else { 111 return -1; 112 } 113 }); 114 115 } 116 117 /** 118 * 規約 119 * <p> 120 * reduce(T iden, BinaryOperator b):可以將流中元素反復結合起來,得到一個值。返回T,其中iden是初始值 121 * reduce(BinaryOperator b):可以將流中元素反復結合起來,得到一個值。返回Optional<T> 122 */ 123 public static void test5() { 124 // 計算:100+1+2+3+4+5+5+5 125 final Integer sum = integerList.stream().reduce(100, (x, y) -> x + y); 126 final Optional<Integer> sumOptional = integerList.stream().reduce((x, y) -> x + y); 127 } 128 129 /** 130 * 收集 131 * 常用: 132 * 1、將流元素收集到List:List<Employee> emps= list.stream().collect(Collectors.toList()); 133 * 2、將流元素收集到Set:List<Employee> emps= list.stream().collect(Collectors.toSet()); 134 * 3、連接流中每個字符串:String str= list.stream().map(Employee::getName).collect(Collectors.joining()); 135 * 4、分組: Map<Emp.Status, List<Emp>> map= list.stream().collect(Collectors.groupingBy(Employee::getStatus)); 136 * 137 * 不常用: 138 * 1、根據true或false進行分區:Map<Boolean,List<Emp>>vd= list.stream().collect(Collectors.partitioningBy(Employee::getManage)); 139 * 2、根據比較器選擇最大值:Optional<Emp>max= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary))); 140 * 3、根據比較器選擇最小值:Optional<Emp> min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary))); 141 * 4、將流元素收集到任意指定集合:Collection<Employee> emps=list.stream().collect(Collectors.toCollection(ArrayList::new)); 142 * 5、計算流中元素的個數:long count = list.stream().collect(Collectors.counting()); 143 * 6、對流中元素的屬性求和:int total=list.stream().collect(Collectors.summingInt(Employee::getSalary)); 144 * 7、計算流中元素Integer屬性的平均值:double avg= list.stream().collect(Collectors.averagingInt(Employee::getSalary)); 145 */ 146 public static void test6() { 147 } 148 149 /** 150 * 並行流與串行流 151 * 並行流就是把一個內容分成多個數據塊,並用不同的線程分別處理每個數據塊的流。 152 * 底層:fork/join 153 * Stream API可以聲明性地通過parallel()與sequential()在並行流與順序流之間進行切換 154 */ 155 public static void test7(){ 156 long start = System.currentTimeMillis(); 157 158 final OptionalLong sum = LongStream.rangeClosed(0, 100000000000L) 159 .parallel() 160 .reduce(Long::sum); 161 162 System.out.println(sum + "-" + (System.currentTimeMillis() - start)); 163 } 164 165 public static void main(String[] args) { 166 test7(); 167 } 168 }
三、Optional
1 import java.util.Optional; 2 3 /** 4 * @author zhaojigang 5 * @date 2018/5/19 6 */ 7 public class OptionalTest { 8 9 public static void main(String[] args) { 10 // String godName = "shijia"; 11 String godName = null; 12 // 常用方式 13 final String god = Optional.ofNullable(godName).orElse("yesu"); 14 System.out.println(god); 15 } 16 }
四、日期時間API
1 import java.time.Duration; 2 import java.time.Instant; 3 import java.time.LocalDateTime; 4 import java.time.format.DateTimeFormatter; 5 6 /** 7 * @author zhaojigang 8 * @date 2018/5/19 9 */ 10 public class TimeTest { 11 12 /** 13 * 一、日期創建: 14 * LocalDate localDate = LocalDate.now(); 15 * LocalTime localTime = LocalTime.now(); 16 * LocalDateTime localDateTime = LocalDateTime.now(); 17 * 18 * LocalDate localDate = LocalDate.of(2016, 10, 26); 19 * LocalTime localTime = LocalTime.of(02, 22, 56); 20 * LocalDateTime localDateTime = LocalDateTime.of(2016, 10, 26, 12, 10, 55); 21 * 22 * 二、日期加減運算 23 * plusDays, plusWeeks, plusMonths, plusYears 24 * minusDays, minusWeeks, minusMonths, minusYears 25 * plus, minus 26 * 27 * 三、日期比較計算 28 * isBefore, isAfter 29 * 30 * 四、是否閏年 31 * isLeapYear 32 * 33 * 五、時間戳與時間間隔運算 34 * Instant 時間戳:以Unix元年(傳統的設定為UTC時區1970年1月1日午夜時分)開始所經歷的描述進行運算 35 * Duration:用於計算兩個“時間”間隔 36 * Period:用於計算兩個“日期”間隔 37 * 38 * 六、時間校正器 39 * TemporalAdjuster/TemporalAdjusters 調整時間:例如獲取下一個周日等 40 * 41 * 七、日期解析和格式化 42 * java.time.format.DateTimeFormatter類 43 */ 44 public static void main(String[] args) { 45 /** 46 * 計算時間間隔 47 */ 48 Instant in1 = Instant.now(); 49 Instant in2 = Instant.now(); 50 System.out.println(Duration.between(in1, in2).toMillis()); 51 52 /** 53 * 日期格式化 54 */ 55 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 56 LocalDateTime time1 = LocalDateTime.now(); 57 String formatDateTime = time1.format(formatter); 58 59 /** 60 * 日期解析 61 */ 62 LocalDateTime dateTime = LocalDateTime.parse(formatDateTime, formatter); 63 } 64 }
日期操作我們通常會使用Apache commons包,但是這樣就會引入一個包,能夠使用java本身的就是用java本身的。
3 java8新特性總結