Java8 學習總結

Lambda 表達式

Lambda 是一個匿名函數(shù),我們可以把 Lambda 表達式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進行傳遞)。可以寫出更簡潔、更靈活的代碼。作為一種更緊湊的代碼風格,使Java的語言表達能力得到了提升。

Lambda 表達式在Java 語言中引入了一個新的語法元素和操作符。這個操作符為 “->” , 該操作符被稱為 Lambda 操作符或箭頭操作符。它將 Lambda 分為兩個部分:

- 左側:指定了 Lambda 表達式需要的所有參數(shù)

- 右側:指定了 Lambda 體,即 Lambda 表達式要執(zhí)行的功能。

Lambda 表達式語法

語法格式一:無參,無返回值,Lambda 體只需一條語句

Runnable runnable = () -> System.out.println("hello Lambda");

語法格式二:Lambda 需要一個參數(shù)

Consumer<String> con = (t) -> System.out.println(t);

語法格式三:Lambda 只需要一個參數(shù)時,參數(shù)的小括號可以省略

Consumer<String> con = t -> System.out.println(t);

語法格式四:Lambda 需要兩個參數(shù),并且有返回值

Comparator<Integer> comparator = (x,y) -> {

? ? ? ? System.out.println("相加結果是:"+(x+y));

? ? ? ? return Integer.compare(x,y);

? ? };

語法格式五:當 Lambda 體只有一條語句時,return 與大括號可以省略

Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);

語法格式六:數(shù)據(jù)類型可以省略,因為可由編譯器推斷得出,稱為“類型推斷”

Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);

類型判斷

Lambda 表達式中無需指定類型,程序依然可以編譯,這是因為 javac 根據(jù)程序的上下文,在后臺推斷出了參數(shù)的類型。Lambda 表達式的類型依賴于上下文環(huán)境,是由編譯器推斷出來的。這就是所謂的“類型推斷”。

函數(shù)式接口

只包含一個抽象方法的接口,稱為函數(shù)式接口。

可以通過 Lambda 表達式來創(chuàng)建該接口的對象。(若 Lambda 表達式拋出一個受檢異常,那么該異常需要在目標接口的抽象方法上進行聲明)。

我們可以在任意函數(shù)式接口上使用 @FunctionalInterface 注解,這樣做可以檢查它是否是一個函數(shù)式接口,同時 javadoc 也會包含一條聲明,說明這個接口是一個函數(shù)式接口。

Java 內(nèi)置四大核心函數(shù)式接口

方法引用

當要傳遞給Lambda體的操作,已經(jīng)有實現(xiàn)的方法了,可以使用方法引用(實現(xiàn)抽象方法的參數(shù)列表,必須與方法引用方法的參數(shù)列表保持一致。)方法引用:使用操作符 “::” 將方法名和對象或類的名字分隔開來。

如下三種主要使用情況:

- 對象::實例方法

- 類::靜態(tài)方法

- 類::實例方法

使用注意事項:

* 1.Lambda 體中調(diào)用方法的參數(shù)列表與返回值類型,要與函數(shù)式接口中抽象方法的函數(shù)列表和返回值類型保持一致。

* 2.若Lambda 參數(shù)列表中第一個參數(shù)是實例方法調(diào)用者,第二個參數(shù)是實例方法的參數(shù) 可以使用 ClassName :: method

構造器引用

與函數(shù)式接口相結合,自動與函數(shù)式接口中方法兼容。可以把構造器引用賦值給定義的方法,與構造器參數(shù)列表要與接口中抽象方法的參數(shù)列表一致!

格式: ClassName::new

數(shù)組引用

格式: type[] :: new

? ? /**

? ? * 方法引用:若Lambda 體中的內(nèi)容有方法已經(jīng)實現(xiàn)了,可以使用"方法引用"

? ? */

? ? public class TestMethodRef {

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? Consumer<String> con = (x) -> System.out.println(x);

? ? ? ? ? ? con.accept("shuai");

? ? ? ? ? ? //方法引用,對象::實例方法名

? ? ? ? ? ? Consumer<String> consumer = System.out::println;

? ? ? ? ? ? consumer.accept("test");

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? Person person = new Person();

? ? ? ? ? ? Supplier<String> supplier = () -> person.getName();

? ? ? ? ? ? String str = supplier.get();

? ? ? ? ? ? System.err.println(str);

? ? ? ? ? ? //方法引用,對象::實例方法名

? ? ? ? ? ? Supplier<Integer> sup = person::getAge;

? ? ? ? ? ? Integer age = sup.get();

? ? ? ? ? ? System.out.println(age);

? ? ? ? }

? ? ? ? //類::靜態(tài)方法名

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? Comparator<Integer> com = (x,y) -> Integer.compare(x, y);

? ? ? ? ? ? //使用前提,compare的參數(shù)和返回值與Comparator一致

? ? ? ? ? ? Comparator<Integer> comparator = Integer :: compare;

? ? ? ? }

? ? ? ? //類::實例方法名

? ? ? ? @Test

? ? ? ? public void test4(){

? ? ? ? ? ? BiPredicate<String, String> bp = (x,y) -> x.equals(y);

? ? ? ? ? ? //使用條件:第一個參數(shù)是實例方法調(diào)用者,第二個參數(shù)是實例方法的參數(shù)

? ? ? ? ? ? BiPredicate<String, String> biPredicate = String :: equals;

? ? ? ? }

? ? ? ? //構造器引用

? ? ? ? @Test

? ? ? ? public void test5(){

? ? ? ? ? ? Supplier<Person> sup = () -> new Person();

? ? ? ? ? ? //構造器引用方式

? ? ? ? ? ? Supplier<Person> supplier = Person :: new;

? ? ? ? ? ? Person person = supplier.get();

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? ? ? //構造器引用

? ? ? ? @Test

? ? ? ? public void test6(){

? ? ? ? ? ? Function<Integer, Person> fun = (x) -> new Person(x);

? ? ? ? ? ? Function<Integer, Person> function = Person :: new;

? ? ? ? ? ? Person person = function.apply(2);

? ? ? ? ? ? System.out.println(person);

? ? ? ? ? ? System.out.println("--------------------");

? ? ? ? ? ? BiFunction<String, Integer, Person> biFunction = Person :: new;

? ? ? ? ? ? Person person2 = biFunction.apply("張三", 23);

? ? ? ? ? ? System.out.println(person2);

? ? ? ? }

? ? ? ? //數(shù)組引用

? ? ? ? @Test

? ? ? ? public void test7(){

? ? ? ? ? ? Function<Integer, String[]> fun = (x) -> new String[x];

? ? ? ? ? ? String[] strs = fun.apply(8);

? ? ? ? ? ? System.out.println(strs.length);

? ? ? ? ? ? Function<Integer, String[]> function = String[] :: new;

? ? ? ? ? ? String[] strArray = function.apply(6);

? ? ? ? ? ? System.out.println(strArray.length);

? ? ? ? }

? ? }

Stream API

Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定 希望對集合進行的操作,可以執(zhí)行非常復雜的查找、過濾和映射數(shù)據(jù)等操作。使用Stream API 對集合數(shù)據(jù)進行操作,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫查詢。也可以使用 Stream API 來并行執(zhí)行操作。簡而言之,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式。

Stream

是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。

“集合講的是數(shù)據(jù),流講的是計算!”

1. Stream 自己不會存儲元素。

2. Stream 不會改變源對象。相反,他們會返回一個持有結果的新Stream。

3. Stream 操作是延遲執(zhí)行的。這意味著他們會等到需要結果的時候才執(zhí)行。

Stream 的操作三個步驟

創(chuàng)建 Stream

一個數(shù)據(jù)源(如:集合、數(shù)組),獲取一個流

中間操作

一個中間操作鏈,對數(shù)據(jù)源的數(shù)據(jù)進行處理

終止操作(終端操作)

一個終止操作,執(zhí)行中間操作鏈,并產(chǎn)生結果

創(chuàng)建Stream?

Java8 中的 Collection 接口被擴展,提供了兩個獲取流的方法:

- default Stream stream() : 返回一個順序流

- default Stream parallelStream() : 返回一個并行流

Java8 中的 Arrays 的靜態(tài)方法 stream() 可以獲取數(shù)組流:

- static Stream stream(T[] array): 返回一個流

可以使用靜態(tài)方法 Stream.of(), 通過顯示值創(chuàng)建一個流。它可以接收任意數(shù)量的參數(shù)。

- public static Stream of(T… values) : 返回一個流

可以使用靜態(tài)方法 Stream.iterate() 和Stream.generate(), 創(chuàng)建無限流。

- 迭代

public static Stream iterate(final T seed, final UnaryOperator f)

- 生成

public static Stream generate(Supplier s) :

? ? //創(chuàng)建Stream

? ? @Test

? ? public void test1(){

? ? ? ? //1.可以通過Collection系列集合提供的stream() 或parallelStream()

? ? ? ? List<String> list = new ArrayList<>();

? ? ? ? Stream<String> stream = list.stream();

? ? ? ? //2.通過Arrays中靜態(tài)方法 stream() 獲取數(shù)組流

? ? ? ? Person[] persons = new Person[10];

? ? ? ? Stream<Person> stream2 = Arrays.stream(persons);

? ? ? ? //3.通過Stream類中的靜態(tài)方法 of()

? ? ? ? Stream<String> stream3 = Stream.of("a","b","c");

? ? ? ? //4.創(chuàng)建無限流

? ? ? ? //迭代

? ? ? ? Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);

? ? ? ? stream4.limit(8).forEach(System.out :: println);

? ? ? ? //生成

? ? ? ? Stream.generate(() -> Math.random()).limit(6)

? ? ? ? ? ? .forEach(System.out :: println);

? ? }? ? ?

Stream 的中間操作

多個中間操作可以連接起來形成一個流水線,除非流水線上觸發(fā)終止操作,否則中間操作不會執(zhí)行任何的處理!而在終止操作時一次性全部處理,稱為“惰性求值”。

? ? /**

? ? * Stream API的中間操作

? ? */

? ? public class TestSteamAPI2 {

? ? ? ? List<Person> persons = Arrays.asList(

? ? ? ? ? ? ? ? new Person(2, "錢四", 24),

? ? ? ? ? ? ? ? new Person(1, "張三", 33),

? ? ? ? ? ? ? ? new Person(2, "李四", 24),

? ? ? ? ? ? ? ? new Person(3, "王五", 65),

? ? ? ? ? ? ? ? new Person(4, "趙六", 26),

? ? ? ? ? ? ? ? new Person(5, "陳七", 27)

? ? ? ? );

? ? ? ? //內(nèi)部迭代,由Stream API完成

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? //中間操作,不會執(zhí)行任何操作

? ? ? ? ? ? Stream<Person> stream = persons.stream()

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .filter((e) -> {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("Stream的中間操作");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return e.getAge() > 25;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? //終止操作,一次性執(zhí)行全部內(nèi)容,即"惰性求值"

? ? ? ? ? ? stream.forEach(System.out :: println);

? ? ? ? }

? ? ? ? //外部迭代

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? Iterator<Person> iterator = persons.iterator();

? ? ? ? ? ? while (iterator.hasNext()) {

? ? ? ? ? ? ? ? System.out.println(iterator.next());

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //limit,截斷

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? .filter((e) -> {

? ? ? ? ? ? ? ? ? ? System.out.println("迭代操作"); //短路

? ? ? ? ? ? ? ? ? ? return e.getAge() > 24;

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .limit(2)

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? }

? ? ? ? //跳過skip,distinct去重(要重寫equals和hashcode)

? ? ? ? @Test

? ? ? ? public void test4(){

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? ? ? .filter((e) -> e.getAge() > 23)

? ? ? ? ? ? ? ? ? ? .skip(2)

? ? ? ? ? ? ? ? ? ? .distinct()

? ? ? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? }

? ? ? ? //映射

? ? ? ? @Test

? ? ? ? public void test5(){

? ? ? ? ? ? List<String> list = Arrays.asList("a","bb","c","d","e");

? ? ? ? ? ? list.stream().map((str) -> str.toUpperCase())

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? ? ? System.out.println("---------------");

? ? ? ? ? ? persons.stream().map((Person :: getName)).forEach(System.out :: println);

? ? ? ? ? ? System.out.println("---------------");

? ? ? ? ? ? Stream<Stream<Character>> stream = list.stream()

? ? ? ? ? ? ? ? .map(TestSteamAPI2 :: filterCharacter);

? ? ? ? ? ? stream.forEach((s) -> {

? ? ? ? ? ? ? ? s.forEach(System.out :: println);

? ? ? ? ? ? });

? ? ? ? ? ? System.out.println("-----------------");

? ? ? ? ? ? //flatMap

? ? ? ? ? ? Stream<Character> stream2 = list.stream()

? ? ? ? ? ? ? ? .flatMap(TestSteamAPI2 :: filterCharacter);

? ? ? ? ? ? stream2.forEach(System.out :: println);

? ? ? ? }

? ? ? ? //處理字符串

? ? ? ? public static Stream<Character> filterCharacter(String str){

? ? ? ? ? ? List<Character> list = new ArrayList<>();

? ? ? ? ? ? for (Character character : str.toCharArray()) {

? ? ? ? ? ? ? ? list.add(character);

? ? ? ? ? ? }

? ? ? ? ? ? return list.stream();

? ? ? ? }

? ? ? ? //排序

? ? ? ? @Test

? ? ? ? public void test6(){

? ? ? ? ? ? List<String> list = Arrays.asList("bb","c","aa","ee","ddd");

? ? ? ? ? ? list.stream()

? ? ? ? ? ? ? ? .sorted() //自然排序

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? ? ? System.out.println("------------");

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? ? ? .sorted((p1,p2) -> {

? ? ? ? ? ? ? ? ? ? ? ? if (p1.getAge() == p2.getAge()) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return p1.getName().compareTo(p2.getName());

? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return p1.getAge() - p2.getAge();

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }).forEach(System.out :: println);

? ? ? ? }

? ? }

接口中的默認方法與靜態(tài)方法

接口中的默認方法

Java 8中允許接口中包含具有具體實現(xiàn)的方法,該方法稱為“默認方法”,默認方法使用 default 關鍵字修飾。

接口默認方法的”類優(yōu)先”原則

若一個接口中定義了一個默認方法,而另外一個父類或接口中又定義了一個同名的方法時

- 選擇父類中的方法。如果一個父類提供了具體的實現(xiàn),那么接口中具有相同名稱和參數(shù)的默認方法會被忽略。

- 接口沖突。如果一個父接口提供一個默認方法,而另一個接口也提供了一個具有相同名稱和參數(shù)列表的方法(不管方法是否是默認方法),那么必須覆蓋該方法來解決沖突。

接口中的靜態(tài)方法

Java8 中,接口中允許添加靜態(tài)方法。

? ? public interface MyInterface {

? ? ? ? default String getName(){

? ? ? ? ? ? return "接口測試";

? ? ? ? }

? ? ? ? public static void show(){

? ? ? ? ? ? System.out.println("接口中的靜態(tài)方法");

? ? ? ? }

? ? }

新特性:

? ? public static void main(String[] args) throws InterruptedException, ExecutionException {

? ? ? ? DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");

? ? ? ? Callable<LocalDate> callable = new Callable<LocalDate>() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public LocalDate call() throws Exception {

? ? ? ? ? ? ? ? return LocalDate.parse("20170521",dtf);

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? ExecutorService pool = Executors.newFixedThreadPool(10);

? ? ? ? List<Future<LocalDate>> results = new ArrayList<>();

? ? ? ? for (int i = 0; i < 8; i++) {

? ? ? ? ? ? results.add(pool.submit(callable));

? ? ? ? }

? ? ? ? for (Future<LocalDate> future : results) {

? ? ? ? ? ? System.out.println(future.get());

? ? ? ? }

? ? ? ? //關閉資源

? ? ? ? pool.shutdown();

}

LocalDate LocalTime LocalDateTime

? ? //1.LocalDate LocalTime LocalDateTime

? ? @Test

? ? public void test1(){

? ? ? ? LocalDateTime ldt = LocalDateTime.now();

? ? ? ? System.out.println(ldt);

? ? ? ? LocalDateTime ldt2 = LocalDateTime.of(2017, 05, 21, 21, 43, 55, 33);

? ? ? ? System.out.println(ldt2);

? ? ? ? LocalDateTime ldt3 = ldt.plusYears(3);

? ? ? ? System.out.println(ldt3);

? ? ? ? LocalDateTime ldt4 = ldt.minusMonths(5);

? ? ? ? System.out.println(ldt4);

? ? }

解析與格式化

java.time.format.DateTimeFormatter 類

該類提供了三種格式化方法:

- 預定義的標準格式

- 語言環(huán)境相關的格式

- 自定義的格式

? ? //DateTimeFormatter:格式化時間/日期

? ? @Test

? ? public void test6(){

? ? ? ? DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;

? ? ? ? LocalDateTime ldt = LocalDateTime.now();

? ? ? ? System.out.println(ldt);

? ? ? ? String format = ldt.format(dtf);

? ? ? ? System.out.println(format);

? ? ? ? System.out.println("------------");

? ? ? ? DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

? ? ? ? String format2 = dtf2.format(ldt);

? ? ? ? System.out.println(format2);

? ? ? ? LocalDateTime ldt2 = ldt.parse(format2,dtf2);

? ? ? ? System.out.println(ldt2);

? ? }

HashMap

HashMap:減少碰撞,位置相同時,條件達到鏈表上超過8個,總數(shù)超過64個時,數(shù)據(jù)結構改為紅黑樹。

ConcurrentHashMap:取消鎖分段,與HashMap相同,達到條件時,數(shù)據(jù)結構改為紅黑樹。

Optional 類

Optional 類(java.util.Optional) 是一個容器類,代表一個值存在或不存在,原來用 null 表示一個值不存在,現(xiàn)在 Optional 可以更好的表達這個概念。并且可以避免空指針異常。

常用方法:

- Optional.of(T t) : 創(chuàng)建一個 Optional 實例

- Optional.empty() : 創(chuàng)建一個空的 Optional 實例

- Optional.ofNullable(T t):若 t 不為 null,創(chuàng)建 Optional 實例,否則創(chuàng)建空實例

- isPresent() : 判斷是否包含值

- orElse(T t) : 如果調(diào)用對象包含值,返回該值,否則返回t

- orElseGet(Supplier s) :如果調(diào)用對象包含值,返回該值,否則返回 s 獲取的值

- map(Function f): 如果有值對其處理,并返回處理后的Optional,否則返回 Optional.empty()

- flatMap(Function mapper):與 map 類似,要求返回值必須是Optional

? ? /**

? ? * Optional類

? ? */

? ? public class TestOptional {

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? //參數(shù)不能為空

? ? ? ? ? ? Optional<Person> op = Optional.of(new Person());

? ? ? ? ? ? Person person = op.get();

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? //構建空optional

? ? ? ? ? ? Optional<Person> op = Optional.empty();

? ? ? ? ? ? System.out.println(op.get());

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? //如果為null,調(diào)用empty,如果不為null,調(diào)用of

? ? ? ? ? ? Optional<Person> op = Optional.ofNullable(null);

? ? //? ? ? Optional<Person> op = Optional.ofNullable(new Person());

? ? ? ? ? ? if (op.isPresent()) {

? ? ? ? ? ? ? ? System.out.println(op.get());

? ? ? ? ? ? }

? ? ? ? ? ? //有值就用值,沒值就替代

? ? ? ? ? ? Person person = op.orElse(new Person("張三", 23));

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? }

重復注解與類型注解

Java 8對注解處理提供了兩點改進:可重復的注解及可用于類型的注解。

? ? @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

? ? @Retention(RetentionPolicy.RUNTIME)

? ? public @interface MyAnnotations {

? ? ? ? MyAnnotation[] value();

? ? }

? ? @Repeatable(MyAnnotations.class)

? ? @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ElementType.TYPE_PARAMETER})

? ? @Retention(RetentionPolicy.RUNTIME)

? ? public @interface MyAnnotation {

? ? ? ? String value() default "aric";

? ? }

? ? /**

? ? * 重復注解與類型注解

? ? */

? ? public class TestAnnotation {

? ? ? ? @MyAnnotation("hello")

? ? ? ? @MyAnnotation("test")

? ? ? ? public void show(@MyAnnotation("a") String str){

? ? ? ? ? ? System.out.println(str);

? ? ? ? }

? ? }

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 點贊+收藏 就學會系列,文章收錄在 GitHub JavaEgg ,N線互聯(lián)網(wǎng)開發(fā)必備技能兵器譜 Java8早在2...
    JavaKeeper_海星閱讀 350評論 0 0
  • 1. 為什么要用流? 先看下流處理有什么優(yōu)勢吧:下面兩段代碼都是用來返回低熱量的菜肴名稱的,并按照卡路里排序,一個...
    little田同學閱讀 569評論 0 1
  • java8新特性 原創(chuàng)者:文思 一、特性簡介 速度更快 代碼更少,增加了Lambda 強大的Stream API ...
    文思li閱讀 3,065評論 1 1
  • 0、java新特性簡介 速度更快數(shù)據(jù)結構發(fā)生變化jvm內(nèi)存模型變化 新生代、老年代、永久區(qū)、方法計數(shù)器、棧新的垃圾...
    liangflying閱讀 468評論 0 1
  • JAVA 8 新特性 Java 8 應該是目前項目中使用最多的版本,之前有使用過它的一些新特性,了解一些基本的用法...
    caoshenyang閱讀 647評論 0 2