Java8

Java8容許咱們給接口添加多個非抽象的方法實現,非靜態方法只須要使用 default關鍵字便可,也能夠稱爲Defender方法,或者虛擬擴展方法(Virtual extension methods)。java

  1. 函數接口(@FunctionalInterface):只包含一個抽象方法的接口,因此也稱爲SAM(Single Abstract Method)類型的接口。默認方法與靜態方法並不影響函數式接口的契約,能夠任意使用。
  2. Lambda表達式:實現函數接口,並返回該接口的一個匿名實現類的對象。都是延遲執行的。訪問外部的部變量都是final

內部類和匿名類編譯的class文件命名規則

    不管是不是接口、抽象類、實體類,在new的同時進行修改 都會編譯成匿名類。app

  • 內部類的class文件命名是:主類+$+內部類名
  • 匿名類的class文件命名是:主類+$+(1,2,3....) (按出現順序)
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.google.common.base.Splitter;

public class Test {

    public static Stream<String> convert(String s) {
        new Test() {
            @Override
            public void dosomething() {
                System.out.println("dosomething");
            }
        };
        return Splitter.on(",").splitToList(s).stream();
    }

    public void dosomething() {
    }

    class A {
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList("a,a,a,a", "b,b,b,b");
        Stream<String> result = list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String t) {
                return true;
            }
        }).flatMap(Test::convert);
       // Stream<String> result = list.stream().filter(t -> t != null).flatMap(Test::convert);

        System.out.println(result.collect(Collectors.toList()).toString());
    }
}


若是將代碼中的Predicate寫成Lambda表達式則不編譯匿名內部類:
ide

同名default方法如何選擇

若是一個接口InterfaceA中定義了一個默認方法,而另一個父類或接口InterfaceB中又定一個同名的方法:函數

  一、 選擇父類中的方法。若是一個父類提供了具體的實現方法,那麼接口中同名同參數的默認方法被忽略。(類優先原則ui

  二、 接口衝突。 若是一個父接口提供了一個默認的方法,而另一個接口也提供了同名同參數的方法(不管是不是默認方法),必須經過覆蓋該方法來解決衝突(InterfaceB.super.doSomething())google

經常使用函數接口表達式

接口名spa

參數類型code

返回類型對象

抽象方法blog

描述

Supplier<T>

T

get    

無輸入參數,返回T的實例

Consumer<T>

T

void

accept      

在T上執行一個操做,無返回結果;可能會更改輸入參數的內部狀態

BiConsumer<T, U>

T, U

void

accept      

處理T類型和U類型的值

Function<T,R>

T

R

apply   

輸入參數爲T的實例,返回R的實例

BiFunction<T, U , R>

T, U

R

apply   

輸入參數爲T,U的實例,返回R的實例

UnaryOperator<T> extends Function<T, T>

T

T

apply    

對類型T進行的一元操做,返回T

BinaryOperator<T> extends BiFunction<T,T,T>

T

T

apply    

對類型T進行的二元操做,返回T

Predicate<T>

T

boolean

test    

布爾類型的函數,輸入參數爲T的實例,返回boolean值

BiPredicate<T, U>

T, U

boolean

test    

含兩個參數計算boolean值的函數

Map

  • V put(K key, V value)  :  返回Key對應的原Value值
  • Object compute(Object key, BiFunction remappingFunction) :
    使用remappingFunction根據原key-oldValue對計算一個新結果newValue。
    newValue不爲null,則put並返回newValue;不然刪除原key-value對,並返回null。
    V compute(K key,  BiFunction<? super K, ? super V, ? extends V> mappingFunction) {
      Objects.requireNonNull(remappingFunction);
      V oldValue = get(key);
     
      V newValue = remappingFunction.apply(key, oldValue);
      if (newValue == null) {
      // delete mapping
      if (oldValue != null || containsKey(key)) {
      // something to remove
      remove(key);
      return null;
      } else {
      // nothing to do. Leave things as they were.
      return null;
      }
      } else {
      // add or replace old mapping
      put(key, newValue);
      return newValue;
      }
      }
  • Object computeIfAbsent(Object key, Function mappingFunction) :
    若是Key對應的value不爲Null:則返回oldValue;
    不然使用mappingFunction根據key計算一個新結果newValue,若newValue不爲空則put新值 並返回newValue;不然返回null。
    V computeIfAbsent(K key,  Function<? super K, ? extends V> mappingFunction) {
      Objects.requireNonNull(mappingFunction);
      V v;
      if ((v = get(key)) == null) {
      V newValue;
      if ((newValue = mappingFunction.apply(key)) != null) {
      put(key, newValue);
      return newValue;
      }
      }
    
      return v;
      }
  • Object computeIfPresent(Object key, BiFunction remappingFunction) : 
    若是Key對應的value爲null:則返回null;
    不然使用remappingFunction根據key-oldValue計算一個新結果newValue,若newValue爲null時,刪除key-oldValue對 並返回null,  不然 put新值 並返回newValue;
    V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
      Objects.requireNonNull(remappingFunction);
      V oldValue;
      if ((oldValue = get(key)) != null) {
      V newValue = remappingFunction.apply(key, oldValue);
      if (newValue != null) {
      put(key, newValue);
      return newValue;
      } else {
      remove(key);
      return null;
      }
      } else {
             return null;
      }
      }
  • Object getOrDefault(Object key, V defaultValue):
    獲取指定的key對應的value。若是該key不存在,則返回defaultValue
  • Object merge(Object key, Object value, BiFunction remappingFunction):
    原值oldValue爲空,取初始化值value,不然執行 remappingFunction根據oldValue-value計算出新的newValue。若是newValue爲空,刪除該Key; 不然put新值。整個方法返回newValue。
    V merge(K key, V value,  BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
      Objects.requireNonNull(remappingFunction);
      Objects.requireNonNull(value);
      V oldValue = get(key);
      V newValue = (oldValue == null) ? value :
      remappingFunction.apply(oldValue, value);
      if(newValue == null) {
             remove(key);
      } else {
             put(key, newValue);
      }
      return newValue;
      }
  • Object putIfAbsent(Object key, Object value) :
    指定的key對應的value不爲null, 返回oldValue ; 不然添加新值,並返回null。

    default V putIfAbsent(K key, V value) {
      V v = get(key);
      if (v == null) {
          v = put(key, value);
      }
           return v;
      }
  • Object replace(Object key, Object value):
    將Map中指定key對應的value替換成新value並返回被替換掉的舊值。若是key在Map中不存在,該方法不會添加key-value對,而是返回null

  • Boolean replace(K key, V oldValue, V newValue):
    將Map中指定的key-value對的原value替換成新value。若是在Map中找到指定的key-value對,則執行替換並返回true,不然返回false

  • void replaceAll(BiFunction function):
    該方法使用function對原key-value對執行計算,並將計算結果做爲key-value對的value。

flatMap

將嵌套結構扁平化爲一個層次的集合

public static Stream<Character> convert(String s){
List<Character> result = Lists.newArrayList();
for(char c: s.toCharArray())result.add(c);
return result.stream();
}


public static void main(String[] args) {
List<String> a = Arrays.asList("aaaa","bbbb","cccc","dddddd");
Stream<Character> result = a.stream().flatMap(BaseTest::convert);
System.out.println(result.collect(Collectors.toList()).toString());
}

 

forEach使用return執行下一次遍歷

在使用foreach()處理集合時不能使用break和continue這兩個方法,也就是說不能按照普通的for循環遍歷集合時那樣根據條件來停止遍歷。

而若是要實如今普通for循環中的continue效果時,可使用return來達到(也能夠經過throw exception 方式處理),也就是說若是在一個方法的lambda表達式中使用return時,這個方法是不會返回的,而只是執行下一次遍歷。

List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");

list.forEach(str -> {
    System.out.println(str);
    if (str.equals("1")) {
        return;
    }

    System.out.println("hello");
});

相關文章
相關標籤/搜索