Java8新特性---四大类型函数式接口

lambda表达式:将一段代码进行赋值,或入参。
实质:佚名内部类
Runnable接口就是一个函数式接口。
常用的函数式接口:
消费型接口 BiConsumer:俩个入参,无返回值
Consumer :一个入参,无返回值


package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface BiConsumer<T, U> {
  void accept(T t, U u);

  default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
        Objects.requireNonNull(after);
        return (l, r) -> {
            accept(l, r);
            after.accept(l, r);
        };
    }
}

举例:

package learn.builder;

import java.util.function.BiConsumer;
import java.util.function.Supplier;

public class Java8Builder {
    public  class Person{
        private String name ;
        private String number ;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getNumber() {
            return number;
        }
        public void setNumber(String number) {
            this.number = number;
        }
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", number='" + number + '\'' +
                    '}';
        }
    }
    public Supplier<Person> getPerson = Person::new;
    public BiConsumer<Person,String> changeName = (x, y)->x.setName(y);
    public BiConsumer<Person,String> changeNumber = (x,y)->x.setNumber(y);
}
package learn.test;
import learn.builder.Java8Builder;

public class BuilderTest {
    public static void main(String[] args) {
        Java8Builder jb = new Java8Builder();
        Java8Builder.Person person= jb.getPerson.get();
        jb.changeName.accept(person,"zzx");
        jb.changeNumber.accept(person,"001");
        System.out.println(person);
    }
}

供给型接口 Supplier:无参,有一个返回值

package learn.singleton;
import java.util.function.Supplier;
public enum Singleton5 {
  INSTANCE;
  // 使用JAVA8新特性,写单例
  public static Supplier<Singleton5> getInstance(){
    return  ()->Singleton5.INSTANCE;
  }
  public  void doSomething(){
    System.out.println("Something is Done.");
  }
}
package learn.test;
import learn.singleton.Singleton5;
public class SingletonTest {
    public static void main(String[] args) {
        Singleton5.getInstance().get().doSomething();
    }
}

函数型接口 Function:一个入参,一个返回值
BiFunction:俩个入参,一个返回值

//根据key获取value,不存在则之心function的逻辑生成一个value
//用于延迟加载
//1.8Hash中新增的方法
default 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;
}
private MapperMethodInvoker cachedInvoker(Object proxy, Method method, Object[] args) throws Throwable {
  try {
    return methodCache.computeIfAbsent(method, m -> {
      if (m.isDefault()) {
        try {
          if (privateLookupInMethod == null) {
            return new DefaultMethodInvoker(getMethodHandleJava8(method));
          } else {
            return new DefaultMethodInvoker(getMethodHandleJava9(method));
          }
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException
            | NoSuchMethodException e) {
          throw new RuntimeException(e);
        }
      } else {
        return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
      }
    });
  } catch (RuntimeException re) {
    Throwable cause = re.getCause();
    throw cause == null ? re : cause;
  }
}

断言型接口 Predicate:一个入参,返回boolean。
BiPredicate:俩个入参,返回boolean
junit框架中大量使用

//Optional中的过滤方法
public Optional<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent())
        return this;
    else
        return predicate.test(value) ? this : empty();
}
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
   Optional<AnnotatedElement> element = context.getElement();
   Optional<Disabled> disabled = findAnnotation(element, Disabled.class);
   if (disabled.isPresent()) {
      String reason = disabled.map(Disabled::value).filter(StringUtils::isNotBlank).orElseGet(
         () -> element.get() + " is @Disabled");
      return ConditionEvaluationResult.disabled(reason);
   }

   return ENABLED;
}

主要的就是这四大类型的函数式接口。
此外,我们也可以自定义我们需要的函数式接口,比如springBoot中的CommandLineRunner接口

@FunctionalInterface
public interface CommandLineRunner {

   /**
    * Callback used to run the bean.
    * @param args incoming main method arguments
    * @throws Exception on error
    */
   void run(String... args) throws Exception;
}
@MapperScan("com.itw.learn.dao")
@SpringBootApplication
@Import(DynamicDataSourceRegister.class)
public class MyAppDemo {

   public static void main(String[] args) {
      ApplicationContext ctx =  SpringApplication.run(MyAppDemo.class, args);
   }
   @Bean
   public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
      return args -> {
         System.out.println("来看看 SpringBoot 默认为我们提供的 Bean:");
         String[] beanNames = ctx.getBeanDefinitionNames();
         Arrays.stream(beanNames)
               .filter(t->t.equals("PrimaryDatasource"))
               .forEach(System.out::println);
              };
   }
}

另外,Stream的本质,其实就是对底层四大类型的函数式接口的应用
比如:

void forEach(Consumer<? super T> action);
Stream<T> filter(Predicate<? super T> predicate);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
<R> R collect(Supplier<R> supplier,
              BiConsumer<R, ? super T> accumulator,
              BiConsumer<R, R> combiner);

你可能感兴趣的:(JAVA)