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

相关文章
相关标签/搜索