標籤:rms lan lis 調用 should this 函數式 and import
(原)
在上一篇,用到過這樣一個方法:
list.forEach(new Consumer<Integer>() { @Override public void accept(Integer t) { System.out.println(t); } });
這裡重點看List的foreach方法;
/* * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.lang;import java.util.Iterator;import java.util.Objects;import java.util.Spliterator;import java.util.Spliterators;import java.util.function.Consumer;/** * Implementing this interface allows an object to be the target of * the "for-each loop" statement. See * <strong> * <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a> * </strong> * * @param <T> the type of elements returned by the iterator * * @since 1.5 * @jls 14.14.2 The enhanced for statement */public interface Iterable<T> { /** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator(); /** * Performs the given action for each element of the {@code Iterable} * until all elements have been processed or the action throws an * exception. Unless otherwise specified by the implementing class, * actions are performed in the order of iteration (if an iteration order * is specified). Exceptions thrown by the action are relayed to the * caller. *針對於Iterable的每一個元素去執行給定的動作,直到所有的元素都執行完,或者拋出異常。如果沒有被這個實作類別所指定,動作就會按照迭代的順序來執行。是否拋出異常取決於調用者。 * * @implSpec * <p>The default implementation behaves as if: * <pre>{@code * for (T t : this) * action.accept(t); * }</pre> * * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } /** * Creates a {@link Spliterator} over the elements described by this * {@code Iterable}. * * @implSpec * The default implementation creates an * <em><a href="Spliterator.html#binding">early-binding</a></em> * spliterator from the iterable‘s {@code Iterator}. The spliterator * inherits the <em>fail-fast</em> properties of the iterable‘s iterator. * * @implNote * The default implementation should usually be overridden. The * spliterator returned by the default implementation has poor splitting * capabilities, is unsized, and does not report any spliterator * characteristics. Implementing classes can nearly always provide a * better implementation. * * @return a {@code Spliterator} over the elements described by this * {@code Iterable}. * @since 1.8 */ default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); }}
該方法屬於Iterable介面,並且是1.8新加的方法,它有一個預設的實現方法,用關鍵字default修飾,也就是說,在JDK1.8裡,介面方不再必需是抽象方法了,而是可以有實現體的,並且這個有實現體的方法需要用default關鍵字來修飾。
再來看下Consumer介面。
/** * Represents an operation that accepts a single input argument and returns no * result. Unlike most other functional interfaces, {@code Consumer} is expected * to operate via side-effects. * *代表了一個操作,接收了一個參數,並且不返回結果,不同於大多數其它的函數式介面,Consumer介面期望通過負作用去操作。(也就是說,它可能會操作傳入的參資料,這裡就是它所說的負作用。) * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #accept(Object)}. *這是一個函數式介面,方法是accept * @param <T> the type of the input to the operation * * @since 1.8 */@FunctionalInterfacepublic interface Consumer<T>
對於之前的例子,list.forEach(i -> System.out.println(i)); 這個i是什麼參數呢?由於這裡只有一個參資料,編譯器可以自動的推斷出這個i所屬的類型,同樣,你也可以顯示的指定它的類型,就像這樣list.forEach((Integer i) -> System.out.println(i));,這裡是必需要加上括弧的。
在其它語言中,lambda運算式類型是函數,但是java中,lambda運算式是對象,他們必需依附於一個函數式介面(functional interface)。
所以對於函數式介面的實現,你可以這麼寫:
例如有如下函數式介面:
package com.demo.jdk8;public interface Animal {void eat(String food);}
在上一篇lambda中,對函數式介面有這樣一句話
1、在調用的地方用lambda可以這麼寫(lamdba expressions):
Animal a = food -> {System.out.println(food);};a.eat(“魚”);
這麼寫和寫一個類實現Animal介面,然後再new 出來效是一樣的。但是這種寫法代碼會更簡潔。
2、用方法引用可以這麼寫(method references):
Animal a = System.out::println;a.eat("肉");
Java 8 新特性:2-消費者(Consumer)介面