Java Academy · Oppitunti

Mukautetut funktionaaliset rajapinnat

Määritä oma rajapinta @FunctionalInterface-annotaatiolla.

Oppitunti 4/413 vaihetta

Mukautetut funktionaaliset rajapinnat on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mikä tekee rajapinnasta funktionaalisen

Funktionaalisella rajapinnalla on täsmälleen yksi abstrakti metodi (SAM). Lambda toteuttaa juuri tämän metodin.

  • Oletus- ja staattisia metodeja ei lasketa mukaan rajoitukseen.
interface Greeter {
    String greet(String name);
}

public class Main {
    public static void main(String[] args) {
        Greeter g = name -> "Hello, " + name;
        System.out.println(g.greet("Ada"));
    }
}

@FunctionalInterface-annotaatio

@FunctionalInterface käskee kääntäjää valvomaan yhden abstraktin metodin sääntöä. Jos lisäätte vahingossa toisen abstraktin metodin, kääntäminen epäonnistuu.

@FunctionalInterface
interface Calculator {
    int compute(int a, int b);
}

public class Main {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        System.out.println(add.compute(3, 4));
    }
}

Miksi annotaatiosta on hyötyä

Annotaatio dokumentoi tarkoituksen ja suojaa sopimusta. Ilman sitä rajapinta toimii edelleen funktionaalisena, mutta työtoveri voisi rikkoa sen lisäämällä toisen abstraktin metodin.

@FunctionalInterface
interface Transformer {
    String apply(String input);
}

public class Main {
    public static void main(String[] args) {
        Transformer reverse = s -> new StringBuilder(s).reverse().toString();
        System.out.println(reverse.apply("abc"));
    }
}

Mukautettu geneerinen rajapinta

Rajapintanne voi olla geneerinen aivan kuten sisäänrakennetut rajapinnat.

@FunctionalInterface
interface Converter<S, T> {
    T convert(S source);
}

public class Main {
    public static void main(String[] args) {
        Converter<String, Integer> toInt = Integer::parseInt;
        System.out.println(toInt.convert("123") + 1);
    }
}

Oletusmetodit ovat sallittuja

Funktionaalisella rajapinnalla voi olla default-metodeja. Ne lisäävät toiminnallisuutta rikkomatta yhden abstraktin metodin sääntöä.

@FunctionalInterface
interface Operation {
    int apply(int x);

    default Operation then(Operation next) {
        return x -> next.apply(this.apply(x));
    }
}

public class Main {
    public static void main(String[] args) {
        Operation inc = x -> x + 1;
        Operation dbl = x -> x * 2;
        System.out.println(inc.then(dbl).apply(5));
    }
}

Staattiset metodit ovat myös sallittuja

Staattiset metodit voivat toimia tehdasmetodeina samaan tapaan kuin Function.identity().

@FunctionalInterface
interface Mapper {
    int map(int x);

    static Mapper identity() {
        return x -> x;
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Mapper.identity().map(99));
    }
}

Tarkistettujen poikkeusten heittäminen

Jos abstrakti metodinne määrittää tarkistetun poikkeuksen, lambda voi heittää sen. Sisäänrakennettu Function ei pysty tähän, mikä on yksi syy oman rajapinnan määrittämiseen.

@FunctionalInterface
interface RiskyParser {
    int parse(String s) throws NumberFormatException;
}

public class Main {
    public static void main(String[] args) {
        RiskyParser p = Integer::parseInt;
        System.out.println(p.parse("77"));
    }
}

Mukautettujen rajapintojen välittäminen metodeille

Rajapinnasta tulee parametrin tyyppi, jolloin kutsuja voi välittää toiminnallisuuden lambdojen avulla.

@FunctionalInterface
interface IntCombiner {
    int combine(int a, int b);
}

public class Main {
    static int reduce(int[] arr, IntCombiner c) {
        int acc = arr[0];
        for (int i = 1; i < arr.length; i++) acc = c.combine(acc, arr[i]);
        return acc;
    }

    public static void main(String[] args) {
        int[] data = {1, 2, 3, 4};
        System.out.println(reduce(data, (a, b) -> a + b));
    }
}

Kolmen argumentin rajapinta

JDK tarjoaa valmiina vain yhden ja kahden argumentin rajapinnat. Jos argumentteja on kolme tai enemmän, määrittäkää oma rajapinta.

@FunctionalInterface
interface TriFunction<A, B, C, R> {
    R apply(A a, B b, C c);
}

public class Main {
    public static void main(String[] args) {
        TriFunction<Integer, Integer, Integer, Integer> sum3 = (a, b, c) -> a + b + c;
        System.out.println(sum3.apply(1, 2, 3));
    }
}

Metodiviittaukset sopivat mukautettuihin rajapintoihin

Mikä tahansa metodi, jonka allekirjoitus vastaa SAM:ää, voidaan välittää metodiviittauksena.

@FunctionalInterface
interface StringTest {
    boolean check(String s);
}

public class Main {
    public static void main(String[] args) {
        StringTest blank = String::isBlank;
        System.out.println(blank.check("   "));
    }
}

Anonyymi luokka ja lambda

Lambda on tiivis korvaaja funktionaalisen rajapinnan toteuttavalle anonyymille luokalle. Molemmat tuottavat saman toiminnan.

@FunctionalInterface
interface Action {
    void run();
}

public class Main {
    public static void main(String[] args) {
        Action old = new Action() {
            public void run() { System.out.println("anonymous"); }
        };
        Action neo = () -> System.out.println("lambda");
        old.run();
        neo.run();
    }
}

Pikatarkistus

Mitä @FunctionalInterface takaa?

Kertaus

Määrititte omia funktionaalisia rajapintoja:

  • Funktionaalisella rajapinnalla on täsmälleen yksi abstrakti metodi (SAM).
  • @FunctionalInterface valvoo sääntöä käännösaikana.
  • Oletus- ja staattiset metodit, geneerisyys sekä tarkistetut poikkeukset ovat kaikki sallittuja.
  • Mukautetut rajapinnat täyttävät aukkoja, joita JDK ei kata, kuten kolmen argumentin funktiot tai tarkistettuja poikkeuksia heittävät lambdat.
Aloita maksutta

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
104
Oppitunnit
374

Usein kysytyt kysymykset

Onko oppitunti ”Mukautetut funktionaaliset rajapinnat” ilmainen?

Kyllä – oppitunnin ”Mukautetut funktionaaliset rajapinnat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Mukautetut funktionaaliset rajapinnat”?

Määritä oma rajapinta @FunctionalInterface-annotaatiolla. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Mukautetut funktionaaliset rajapinnat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?

Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Function ja BiFunction
  2. Supplier ja Consumer
  3. Predicate ja koostaminen
  4. Mukautetut funktionaaliset rajapinnat
← Takaisin: Java Academy