您好,登錄后才能下訂單哦!
這篇“java 1.8新特性有哪些”文章,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要參考一下,對于“java 1.8新特性有哪些”,小編整理了以下知識點,請大家跟著小編的步伐一步一步的慢慢理解,接下來就讓我們進入主題吧。
Java主要應用于:1. web開發;2. Android開發;3. 客戶端開發;4. 網頁開發;5. 企業級應用開發;6. Java大數據開發;7.游戲開發等。
java 8發行版是自2004年發行的java 5以來最具有革命性的一個版本。java 8為java語言、編譯器、類庫、開發工具與JVM等帶來了大量新特性。
java 1.8中的幾個新特性
1、lambda表達式
格式:(參數) -> {代碼段}
如:new Thread(() -> {System.out.println("hello world!")}).start(); 這就是lambda表達式。
lambda的實現需要依賴函數式接口,lambda本質上是匿名內部類,jdk1.8以前,如果方法內需要操作其他接口的實現方法,可以通過匿名內部類來實現,
jdk1.8之后可以通過lambda表達式來代替匿名內部類,并且更為簡化。
package java8; public class LambdaDemo { public static void main(String[] args) { //JDK1.8之前使用接口,采用匿名內部類的方式 MyInterface mi = new MyInterface() { @Override public void test() { System.out.println("test"); } }; mi.test(); //JDK1.8之后,使用lambda表達式 MyInterface lmi = () -> { System.out.println("test"); }; lmi.test(); } } //定義一個函數式接口,只有一個抽象方法 interface MyInterface{ void test(); }
函數式接口 : 有且只有一個的抽象方法的接口稱為函數式接口
函數式接口的常用接口 Function, Predicate,Supplier,Consumer 都在java.util.function包下
Function接口:R apply(T t) 接收一個參數并返回一個對象
package java8; import java.util.function.Function; public class LambdaDemo { public static void main(String[] args) { // function的使用 // 傳統模式,第一個泛型:接收的參數類型 第二個泛型,返回的參數類型 Function<String, String> function1 = new Function<String, String>() { @Override public String apply(String t) { return t; } }; // 調用apply方法,并獲取返回結果 String res1 = function1.apply("function的使用"); System.out.println(res1); // lambda的使用,當參數只有一個且不寫參數類型時,"()"可以省略 Function<String, String> function2 = t -> { return t; }; // 調用apply方法,并獲取返回結果 String res2 = function2.apply("function的使用"); System.out.println(res2); } }
Predicate接口 : boolean test(T t) 接收一個參數,返回一個boolean值
常用來比較
package java8; import java.util.function.*; public class LambdaDemo { public static void main(String[] args) { // predicate的使用 // 傳統模式,泛型參數:接收的參數類型 Predicate<Integer> predicate1 = new Predicate<Integer>() { @Override public boolean test(Integer t) { // 大于等于10就為真,否則為假 return t >= 10; } }; // 執行predicate1的方法 System.out.println(predicate1.test(11)); System.out.println(predicate1.test(8)); //使用lambda表達式 Predicate<Integer> predicate2 = new Predicate<Integer>() { @Override public boolean test(Integer t) { // 大于等于10就為真,否則為假 return t >= 10; } }; // 執行predicate1的方法 System.out.println(predicate2.test(11)); System.out.println(predicate2.test(8)); } }
Supplier接口 :T get() 返回一個對象
生產者消費者模式的生產者,只管生產對象
package java8; import java.util.function.*; public class LambdaDemo { public static void main(String[] args) { //Supplier的使用 // 傳統模式,泛型參數:返回的參數類型 Supplier<String> s1 = new Supplier<String>() { @Override public String get() { return new String("supplier"); } }; //調用 System.out.println(s1.get()); // 使用lambda表達式 //當代碼只有一句時,可以省略"{}",不接收參數時,"()"不能省略 Supplier<String> s2 = () -> new String("supplier"); System.out.println(s2.get()); } }
Consumer接口 : accept(T t)接收一個參數,不返回任何值
生產者消費者模式的生產者,只管消費對象
package java8; import java.util.function.*; public class LambdaDemo { public static void main(String[] args) { // Consumer的使用 // 傳統模式,泛型參數:返回的參數類型 Consumer<String> con1 = new Consumer<String>() { @Override public void accept(String t) { System.out.println(t); } }; con1.accept("consumer"); //使用lambda表達式,同時省略"()","{}" Consumer<String> con2 = t -> System.out.println(t); con2.accept("consumer"); } }
lambda實戰用法:
package java8; import java.util.function.*; public class LambdaDemo { public static void main(String[] args) { //Runnable的實現, new Thread(() -> { System.out.println(Thread.currentThread().getName() + " run"); }).start(); System.out.println(Thread.currentThread().getName() + " run"); } }
2、方法引用:
方法引用是指lambda表達式中只有一句方法調用,而這個方法有真實存在,此時就可以用方法引用來替換lambda表達式。
方法引用有四種類型
類名::靜態方法名
對象名::實例方法名
類名::實例方法名
類名::new
package java8; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Supplier; public class MethodReferenceDemo { public static void main(String[] args) { // 定義3個Student對象 Student s1 = new Student("zhangsan", 90); Student s2 = new Student("lisi", 60); Student s3 = new Student("wangwu", 70); // 添加到集合 List<Student> students = Arrays.asList(s1, s2, s3); //普通的lambda實現 // sort接收兩個參數,第一個參數,要排序的集合,第二個參數,Comparator接口的實現 // Collections.sort(students, (stu1,stu2) -> StudentSortUtil.sortByScore(stu1,stu2)); // students.forEach(t -> System.out.println(t.getScore())); // 方法引用1---類名::靜態方法名 // Collections.sort(students, StudentSortUtil::sortByScore); // students.forEach(t -> System.out.println(t.getScore())); //創建實例對象,調用實例對象的方法 StudentSortUtil ssu = new StudentSortUtil(); //普通的lambda實現 // Collections.sort(students, (stu1, stu2) -> ssu.sortByScoreInstance(stu1, stu2)); // students.forEach(t -> System.out.println(t.getScore())); // 方法引用2---對象名::實例方法名 // Collections.sort(students, ssu::sortByScoreInstance); // students.forEach(t -> System.out.println(t.getScore())); /* * 方法引用3---類名::實例方法名 * Student的sortByScore()只有一個參數,而Comparator的實現需要兩個參數,為什么編譯器不報錯? * 這是因為sortByScore是一個普通方法,要使用這個方法肯定要有一個Student類的實例對象來調用 * 而調用的這個方法的對象就作為Comparator的第一個參數對象傳遞進來 * 例String的compareTo()方法,調用這個方法首先要有一個String的實例對象, * 此處str就是這個實例對象,str就作為Comparator的第一個參數 * "hello"這個String對象就作為第二個參數 * String str = new String("str1"); * str.compareTo("hello"); */ Collections.sort(students, Student::sortByScore); //創建一個新的Student對象,使用lambda表達式創建 //不接收參數,返回一個對象,其實就是Supplier接口的實例 Supplier<Student> su1 = () -> new Student(); //方法引用4---類名::new Supplier<Student> su2 = Student::new; //BiConsumer是Consumer的擴展,可以接受兩個參數返回一個值 BiConsumer<String, Integer> bc1 = (name,score) -> new Student(name,score); //替換上面的lambda表達式,需要接收兩個參數,所以調用的是有參構造方法 BiConsumer<String, Integer> bc2 = Student::new; } } //定義一個學生實體類 class Student { private String name; private int score; public Student() { } public Student(String name, int score) { this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public int sortByScore(Student stu) { return this.getScore() - stu.getScore(); } public int sortByName(Student stu) { return this.getName().compareTo(stu.getName()); } } //定義一個學生排序工具類 class StudentSortUtil { public static int sortByScore(Student stu1, Student stu2) { return stu1.getScore() - stu2.getScore(); } public static int sortByName(Student stu1, Student stu2) { return stu1.getName().compareTo(stu2.getName()); } // 普通方法,創建對象才能調用 public int sortByScoreInstance(Student stu1, Student stu2) { return stu1.getScore() - stu2.getScore(); } // 普通方法,創建對象才能調用 public int sortByNameInstance(Student stu1, Student stu2) { return stu1.getName().compareTo(stu2.getName()); } }
3、Stream:
Stream分為中間操作和終止操作,中間操作會繼續返回一個新的流,終止操作返回一個結果。
一行代碼中如果只有中間操作,則不會執行,只有遇見終止操作才會執行。
package java8; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.stream.Stream; public class StreamDemo { public static void main(String[] args) { //Stream的使用 //創建流,參數為可變參數 Stream<Integer> stream = Stream.of(50,66,88); //將Stream轉化為數組 //Object[] array = stream.toArray(); //System.out.println(Arrays.toString(array)); //篩選過濾條件,參數為Predicate,動作自己指定,找到大于60的數 //流分為中間操作和終止操作,節點流會繼續返回一個流對象,終止操作會返回一個結果, //只有中間流,代碼不會執行,只有遇見終止操作才會執行 //stream.filter((target) -> target > 60).forEach(System.out::println); //map對數據進行操作,接收一個Function實例 例:對流中的每個元素都乘以2 stream.map((t) -> 2 * t).forEach(System.out::println); //流的無限模式,會對seed一直執行UnaryOperator的事件,一般和limit配合使用 //skip(n)跳過n個元素,limit(n) 返回n個元素的流 Stream.iterate(0, t -> t + 2).skip(2).limit(6).forEach(System.out::println); //將流轉換為集合對象,第一個參數,傳遞一個Supplier 最終結果類型由此提供 //第二個參數 BiConsumer() 傳遞兩個參數,第一個要操作的集合,第二個當前的流元素 //第三個元素BiConsumer() 傳遞兩個集合,最終合并成一個集合 //類似StringBuffer.append()方法 // stream.collect(() -> new ArrayList<Integer>(), // (target,item)-> target.add(item), // (result,target)-> result.addAll(target)).forEach(System.out::println); //可以使用方法引用簡化 stream.collect(LinkedList::new,LinkedList::add,LinkedList::addAll); } }
以上是“java 1.8新特性有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。