Java8具備更快的運行速度,對底層的數據結構進行了修改,編程書寫代碼更少,提供了更加便利的Stream API,使用並行更簡單,減小了空指針異常的產生,提供了一個容器類減小空指針異常。java
一種匿名函數,相似一段能夠傳遞的代碼,將代碼像傳遞數據同樣在程序中進行傳遞。Lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象(lambda abstraction),是一個匿名函數,即沒有函數名的函數。面試
public class Main { public static void main(String[] args) throws InterruptedException { Runnable runnable = new Runnable() { @Override public void run() { System.out.println("This is a inner class"); } }; //匿名內部類 Thread thread = new Thread(runnable); thread.start(); Runnable runnable_new = () -> System.out.println("This is a Lambda!"); Thread thread_new = new Thread(runnable_new); thread_new.start(); System.out.println("------------------"); } }
Lambda表達式中引入了 -> 操做符,箭頭操做符的左側對應參數列表,箭頭右側爲須要執行的功能,須要「函數式接口」支持,即接口中只有一個抽象方法,可使用@FuctionalInterface修飾,增強檢查。算法
int i = 8; Runnable runnable = () -> System.out.println("This is implement" + i); @FunctionalInterface public interface Test<T,R>{ public void method(); public void method(int i); public int method(int i,int j); public boolean method(int i,float j); public R method(T t1,T T2); }//僅做爲舉例 如下對每種狀況具體進行了實現。 Test test; //無參無返回值 test = () -> System.out.println("This is implement"); //單個參數無返回值 test = (i) -> System.out.prinln("This is i" + i); test = x -> System.out.println("This is i" + i); //兩個參數返回值 Test test = (i,j) -> { System.out.prinln("This is i" + i); System.out.prinln("This is i" + j); return i+j; } //多個參數單條語句返回值 Test test = (i,j) -> i+j; Teat test =(int i,float j) -> !(i+j); //泛型 (i,j) -> i+j;
Lambda表達式須要依賴函數式接口,所以,Java8中內置了多種接口,簡介四種核心函數式接口。編程
Consumer<T> void accept(T t);
Supplier<T> T get();
Function<T,R> R apply(T t);
Predicate<T> boolean test(T t);
BiFunction<T,U,R> R apply(T t,U u); UnaryOperator<T> T apply(T t); BinaryOperator<T> T apply(T t1,T t2); ToIntFunction<T> ToLongFunction<T> ToDubleFunction<T> //返回int、long、double IntFunction<R> LongFunction<R> DoubleFunction<R> //返回R
public void hello(String name,Consumer<String> consumer){ consumer.accept(name); } public String getDate(String data, Supplier<String> supplier){ return data +": "+ supplier.get(); } public String resoleString(String string, Function<String,String> function) { return function.apply(string); } public List<String> filterString(List<String> list,Predicate<String> predicate){ List<String> stringList= new ArrayList<>(); for (String string : list){ if(predicate.test(string)){ stringList.add(string); } } return stringList; } @Test public void test(){ hello("Wang",(name) -> System.out.println("Hello ! I am " + name)); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// String now = getDate("Now",() -> { Date d = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(d); }); System.out.println(now); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// System.out.println("\tThis is a String with blank! "); String result = resoleString("\t\t\tThis is a String with blank! ", (string) -> string.trim()); result = resoleString(result, (string) -> string.substring(5,20)); System.out.println(result); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// List<String> list = Arrays.asList("1234","abcd","http","a","Java and Oracle"); list = filterString(list,(s) -> s.length() > 5); for (String string : list) System.out.println(string); }
Lambda 體中已經實現了的方法,能夠進行使用,使用中只要遵循接口參數列表與構造或方法的參數返回值對應便可,帶給你全新的體驗。api
Consumer<String> consumer = (x) -> System.out.println(x); Consumer<String> consumer = System.out::println; //實現方法的參數列表和引用方法必須保持一致 Integer integer = new Integer(10); Supplier<Integer> supplier = integer::toString; Supplier<ExecutorService> serviceSupplier= Executors::newCachedThreadPool; BiPredicate<String,String> predicate = String::equals; //等效於(x,y) -> x.equals(y); /* 哈哈哈 這仍是Java嗎? 哈哈哈*/ // a.method(b) 纔可以使用
Supplier<Integer> integer = Integer::new; //無參構造器 Function<int,Integer> integer = Integer::new; //一個參數構造器 //構造器的選擇取決於Function中的方法參數,參數列表與構造器必須對應!
Function<Integer,String[]> function = (10) -> new String[x]; Function<Integer,String[]> function = String[]::new;
Stream 不是集合元素,它不是數據結構並不保存數據,它是有關算法和計算的,它更像一個高級版本Iterator。原始版本的Iterator,用戶只能顯式地一個一個遍歷元素並對其執行某些操做;高級版本的 Stream,用戶只要給出須要對其包含的元素執行什麼操做,好比 「過濾掉長度大於 10的字符串」、「獲取每一個字符串的首字母」等,Stream 會隱式地在內部進行遍歷,作出相應的數據轉換,數據源自己能夠是無限的。數組
//使用方法 List<String> list = Arrays.asList("1234","abcd","http","a","Java and Oracle"); Stream<String> stream = list.stream(); int[] ints = new int[20]; IntStream intStream = Arrays.stream(ints); final Stream<int[]> intsStream = Stream.of(ints); Stream<Integer> integerStream = Stream.iterate(0, (seed) -> seed+2); integerStream.limit(10).forEach(System.out::println); Stream.generate(() -> Math.random()).limit(10).forEach(System.out::println);
/*過濾、切片*/ filter 從流中排除指定元素 limit 截斷流,限定流中元素個數 skip(n) 跳過n各元素,超過流元素個數,這返回空流 distinct() 去除重複元素 //鏈式調用中未執行終止操做時(forEach(...)),不會執行任何操做。 //當結果已經知足條件,則不繼續執行後方篩選條件,即具有短路特色。 /*映射*/ map(Function<T t,R r>) 將函數應用到每一個元素中,並將結果映射爲一個新的參數 flatmap 經函數做爲參數應用到每一個元素上,返回流鏈接造成的新流。 /*排序*/ sorted() sorted((a,b) -> a>b?a:b) /* 想到前段時間阿里的面試題 * 一個巨大的數組統計每一個數字的出現次數 */ @Test public void testMap(){ int a[]=new int[1000]; for(int i=0;i<10000;i++){ a[i]=(int) ( Math.random() *100 ); }//模擬數組 final IntStream stream = Arrays.stream(a); stream.distinct().sorted().forEach((i) ->{ System.out.print("This is "+i+ " count : "); long count = Arrays.stream(a).filter((num) -> num == i).count(); System.out.print(count +"\n"); }); }
##查找匹配 allMach #是否匹配全部元素 anyMatch #至少匹配一個元素 noneMatch #是否沒有匹配全部元素 findFirst #返回匹配的第一個元素 findAny #隨機返回一個元素 count #統計元素個數 max #返回最大元素 min #返回最小元素 ##歸約 reduce(初始值,(下一次執行初始值,流中的元素)) Optional<Double> option = employees.stream().map(Employee::getSalary).reduce(Double::sum); #####map-reduce模式##### #將流中的元素反覆匹配執行操做 ##收集 collect #按照必定方式,進行結果收集,即將結果收集起來,可使用一個工具類Collectors employee.stream().map(Employee::getNmae).collect(Collectors.toList()); #最終返回值一個List<String> 列表,存儲姓名屬性 Collectors.groupby #分組 Collectors.summarizingDoutble #數據處理方式 Collectors.joining #字符串
將任務分拆成多個小任務,細分到沒法再繼續分,執行後將全部的結果進行合併獲得結果,在併發包的文章裏,有寫到過,也舉了一個計算的例子,這個框架的特色就是,當任務進行拆分後,採用工做竊取模式,能夠提升計算時對CPU的利用率。工做竊取模式即當前隊列沒法獲取任務時,將去一個其餘拆分隊列的任務進行執行。安全
List.stream().parallelStream() //執行處理時底層使用Fork/Join框架
原接口中只能有全局靜態常量和抽象方法,在java8中能夠給接口添加添加默認方法。默認方法衝突時繼承大於實現,多實現必須重寫衝突默認方法。接口能夠書寫靜態方法,使用時,直接使用接口對象調用。bash
public interface NewInterface{ default String getDefaultMethod(){ return "This is a default Method"; } public static void getStaticMethod(){ System.out.println("This is a static method from a interface !"); }//NewInterface.getStaticMethod() }
原時間相關api存在線程安全問題,使用起來較爲複雜,java8中添加全新的時間api,多線程能夠直接使用,線程安全。數據結構
java.time #日期 java.time.chrono #特殊時間記錄方式 java.time.format #日期格式化 java.time.temporal #運算推算日期 java.time.zone #時區相關設置
//使用時間 @Test public void testNewDate(){ //LocalDate LocalTime LocalDateTime LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime); ----------------------------------- localDateTime = LocalDateTime.of(2018,9,13,23,44); System.out.println(localDateTime); ----------------------------------- localDateTime = localDateTime.plusYears(2); System.out.println(localDateTime); ----------------------------------- localDateTime = localDateTime.minusYears(2); System.out.println(localDateTime); } //時間戳 @Test public void testTimeInstant(){ //Unix 1970.1.1 0.0.0 到如今毫秒 協調世界時 Instant instant = Instant.now(); //設置時間偏移量 instant.atOffset(ZoneOffset.offHours(8)); //獲取毫秒 System.out.println(instant.toEpochMilli()); //運算 Instant.ofEpochSecond(60);//1971.1.1 0.1.0 //計算間隔 Duration duration = Duration.between(instant_end , instant_begin); Period period = Period.between(localDate_end , localDate_begin); }
java8中能夠對方法進行重複註解。多線程
@Repeatable(MoreAnnotations.class) public @interface MoreAnnotation{ String value9() default "註解"; } public @interface MoreAnnotations{ MoreAnnotation[] values(); } @MoreAnnotation @MoreAnnotation @MoreAnnotation public void method(){}
private @NonNull Object obj = null //不支持
碰撞產生的鏈表在長度大於8時將會產生紅黑樹
原16段併發鎖改成CAS算法,同時也具有紅黑樹。