JAVA 8 的新特性


Java8的新特性有:默認方法、函數式接口、lambda表達式、方法引用、StreamOptional、日期API

 一、默認方法:

  接口中的方法可以有方法體但是必須要有static或者default修飾其他的方法都為抽象方法static修飾的方法不能被子接口繼承 方法不能被覆寫只能通過類名.方法名調用default修飾的方法可以被子接口繼承也可以被覆寫調用通過實現類的對象調用

二、函數式接口:

  接口中有且僅有一個抽象方法,一般都有@FuntionalInterface注解,即使沒有注解它還是函數式接口。

常見的函數式接口ComparetorRunnable。

三、lambda表達式:

  可以看成是匿名內部類的簡寫使用lambda表達式的接口必須為函數式接口

    注:匿名內部類會編譯產生兩個class文件,但lambda表達式只會編譯產生一個class文件。

 

    (參數1,參數2…)表示參數列表;->表示連接符;{}內部是方法體
    1、=右邊的類型會根據左邊的函數式接口類型自動推斷;
    2、如果形參列表為空,只需保留();
    3、如果形參只有1個,()可以省略,只需要參數的名稱即可;
    4、如果執行語句只有1句,且無返回值,{}可以省略,若有返回值,則若想省去{},則必須同時省略return,且執行語句也保證只有1句;
    5、形參列表的數據類型會自動推斷;

    6lambda表達式中使用的局部變量默認會被final修飾,不管這個局部變量是在lamdba表達式里定義的還是在表達式外定義的。因此只要是lambda表達式中使用過的局部變量就不能再修改了,不管在什么位置

 

四、方法引用:

    4.1 構造方法引用:

//匿名內部類
PersonFacotry facotry = new PersonFacotry() {
  @override
  public Person createPerson(String name, Integer age){ 
    //其他操作
    return new Person (name, age);
  }
};
//lambda表達式寫法
PersonFacotry facotry1 = (name, age) -> new Person (name, age);

//lambda表達式簡寫(這種寫法的函數式接口有幾個參數,就調用其對應參數個數的構造方法)
PersonFacotry facotry2 = Person:: new;

Person person = facotry.createPerson ( name: "某某某", age: 100) ;
System.out.println(person);

    

    4.2靜態方法引用

public class Test{
    public static void main(string[] args) {
        //匿名內部類方式
        Parseinterface pil = new ParseInterface(){ 
            @override
            public int parse(string str) {
                 return Integer.parselnt(str);
            }
        };

         // Lambda表達式常規寫法
         ParseInterface pi2 = str->Integer.parseInt(str);

        // Lambda表達式簡寫
        ParseInterface pi3 = Integer::parseInt;   
    }
}     

 

    4.3實例方法引用

  Java1.8提供了一個函數式接口Function,接受兩個參數

 

   匿名內部類方式

    string str ="Hello.world";
    //匿名內部類的方式
    Function<String,Boolean> func1= new Function<String,Boolean> (){
        @override
        public Boolean apply(strinq suffix) {
             return str.endswith (suffix);
        }
    };    

 

  Lambda表達式常規寫法

// Lambda表達式常規寫法
String str = "Hello.world";
Function<String,Boolean> func3 = t -> str.endsWith(t);
System.out.println(func3.apply("world"));

 

  Lambda表達式簡寫

// Lambda表達式常規寫法
String str = "Hello.world";
Function<String,Boolean> func2 = t -> str::endsWith;
System.out.println(func2.apply("world"));

 

五、Stream

    Java 8 API添加了一個新的抽象稱為流StreamStream API可以極大提高Java程序員的生產力,讓程序員寫出高效率、干凈、簡潔的代碼

      注意:IO中的流是完全不一樣的。

    在 Java 8 , 集合接口有兩個方法來生成流:

      stream() 為集合創建串行流。常用

      parallelStream() 為集合創建並行流。

  Stream常用方法:

  ForEach:

      Stream 提供了新的方法 'forEach' 來迭代流中的每個數據。以下代碼片段使用 forEach 輸出了10個隨機數:

Random random = new Random();

random.ints().limit(10).forEach(System.out::println);

  map:

    map 方法用於映射每個元素到對應的結果,以下代碼片段使用 map 輸出了元素對應的平方數:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

// 獲取對應的平方數 

List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

  filter:

    filter 方法用於通過設置的條件過濾出元素。以下代碼片段使用 filter 方法過濾出空字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); 

// 獲取空字符串的數量
int count = strings.stream().filter(string -> string.isEmpty()).count();

  limit:

    limit 方法用於獲取指定數量的流。 以下代碼片段使用 limit 方法打印出 10 條數據:

Random random = new Random();

random.ints().limit(10).forEach(System.out::println);

  sorted:

    sorted 方法用於對流進行排序。以下代碼片段使用 sorted 方法對輸出的 10 個隨機數進行排序:

Random random = new Random();

random.ints().limit(10).sorted().forEach(System.out::println);

  並行(parallel)程序:

    parallelStream 是流並行處理程序的代替方法。以下實例我們使用 parallelStream 來輸出空字符串的數量:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

// 獲取空字符串的數量 

int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

    我們可以很容易的在順序運行和並行直接切換。

  Collectors:

Collectors 類實現了很多歸約操作,例如將流轉換成集合和聚合元素。Collectors 可用於返回列表或字符串:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println("篩選列表: " + filtered);

String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));

System.out.println("合並字符串: " + mergedString);

 

六、Optional

  Optional對象可以為空,所以Optional 類的引入很好的解決空指針異常

    通過以下實例來了解Optional類的使用:

Public class User{

  private String name;

  private String password;

  ....

}

以往的判斷方式:

public class Mytest{

  public static void main(String[] args){

       User user = new User();

    User.setPassword(“admin”);

    String name = getPwd(user);

    System.out.println(name);

  }

  public static String getPwd(User u){

    if(u==null){

      return “unknown”;

  }

   return u.getPassword();

}

 

使用Optional

public static String getPwd(User u){

  return Optional.ofNullable(u)

          .map(user->user.getPassword())

          .orElse(“unknown”);

};

 

七、日期Api

Jdk1.8給我們提供了三個本地日期時間類:LocalDateLocalTime LocalDateTime

在不需要處理時區問題的時候,使用本地日期時間APILocalDateLocalTime LocalDateTime 

// 獲取當前的日期時間

 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);

 

在需要處理時區的時候,使用時區的日期時間APIZonedDateTime ):

ZonedDateTime dd= ZonedDateTime.now();
System.out.println(dd);
ZonedDateTime date1 = ZonedDateTime.parse(dd.toString());
System.out.println("date1: " + date1);
ZoneId id = ZoneId.of(ZoneId.SHORT_IDS.get("CTT"));
System.out.println("ZoneId: " + id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("當期時區: " + currentZone);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM