2015-03-23 11 views
11

Czy można zapisać metodę w zmiennej?
Mam klasę, która nazywa się MyFilter i filtruje elementy w różnych polach.
Konstruktor MyFilter powinien zadać 2 rzeczy:Zapisywanie metody w zmiennej, java 8

  1. String, dla artykułów przykład Filtrowanie według języka, "English"
  2. ta powinna być metodą

na przykład:

Mam element i chcę sprawdzić, czy język == String podany do filtra
Potrzebuję więc języka tego przedmiotu, więc Item.getLanguage() ...
Potrzebuję go również dla Item.getTitle(), Item.getId() i tak dalej.

Myślę, że jest to możliwe z lambda, ale nie wiem jak.

+0

See Java Reflection: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html (Methods) oraz http: // docs .oracle.com/javase/7/docs/api/java/lang/Class.html (Classes) – Trinimon

+0

Tak, jest. wszystkie lambda w Javie są rzeczywistymi instancjami klasy wewnętrznej implementującymi odpowiednie interfejsy. deklarujesz ten interfejs i przypisujesz do niego lambdę. – HuStmpHrrr

+0

@HuStmpHrrr - lambdy są instancjami ** funkcjonalnych ** interfejsów. –

Odpowiedz

15

Tak, możesz mieć odniesienie do zmiennej do dowolnej metody. W przypadku prostych metod zwykle wystarczy użyć klas java.util.function.. W przypadku złożonych metod musisz zdefiniować swoją @FunctionalInterface za pomocą tej metody. Przykładem tutaj działa:

import java.util.ArrayList; 
import java.util.List; 
import java.util.function.Consumer; 

public class Main { 

    public static void main(String[] args) { 
     final Consumer<Integer> simpleReference = Main::someMethod; 
     simpleReference.accept(1); 
     simpleReference.accept(2); 
     simpleReference.accept(3); 

     final ComplexInterface complexReference = Main::complexMethod; 
     final String complexResult = complexReference.someMethod("888", 321, new ArrayList<>()); 
     System.out.println(complexResult); 
    } 

    private static void someMethod(int value) { 
     System.out.println(value); 
    } 

    private static String complexMethod(String stringValue, int intValue, List<Long> longList) { 
     final StringBuilder builder = new StringBuilder(); 
     builder.append(stringValue).append(" : ").append(intValue); 
     for (Long longValue : longList) { 
      builder.append(longValue); 
     } 
     return builder.toString(); 
    } 

    @FunctionalInterface 
    public static interface ComplexInterface{ 
     String someMethod(String stringValue, int intValue, List<Long> longList); 
    } 
} 
+0

Czy można również utworzyć mapę HashMap z mapą ? – fangio

+0

Tak, jasne, dlaczego nie. Na przykład powyżej byłoby to "Map >" lub "Map ' – esin88

+0

czy masz pojęcie, jak to działa pod maską? –

0

Można użyć Referencyjna metoda podobnego -

System.out::println 

co jest równoznaczne z wyrażeniem lambda -

x -> System.out.println(x). 

Ponadto można odbicie użytkownikowi przechowywać metody i będzie prace dla wcześniejszej wersji java też.

7

Można używać odwołań do metod Java 8. Możesz użyć operatora "::", aby pobrać odwołanie do metody z obiektu.

import java.util.function.IntConsumer; 

class Test { 
    private int i; 
    public Test() { this.i = 0; } 
    public void inc(int x) { this.i += x; } 
    public int get() { return this.i; } 

    public static void main(String[] args) { 
     Test t = new Test(); 
     IntConsumer c = t::inc; 
     c.accept(3); 
     System.out.println(t.get()); 
     // prints 3 
    } 
} 

Wystarczy się @FunctionalInterface który pasuje podpis metody, które chcesz przechowywać. java.util.function zawiera wybór najczęściej używanych.