2016-08-09 48 views
5

Właśnie zacząłem się uczyć o Java Runnable s i słyszałem o Callable s. Jednak bardzo zmagam się z tym problemem. Chciałbym stworzyć metodę, która przyjmuje funkcję jako argument (czy to jako Callable, Runnable, czy coś innego, o ile mogę po prostu wywołać funkcję jako coolNewFunction(() -> otherFunction(), 100) lub jakiś podobny prosty sposób), a metoda zwraca tablicę zwróconych wartości otherFunction. Na przykład, powiedzmy, że określona funkcjaUtwórz metodę, która generuje wartości xi y kolejnej podanej funkcji

public static int square(int x){ 

    return x * x; 

} 

mogłem wtedy zrobić coś wzdłuż linii:

coolNewFunction(() -> square(), 100) 

a to zwraca tablicę z pierwszych 100 numerów i ich kwadratów (tj {{1, 1}, {2, 4}, {3, 9}...}) . Teraz od nietoperza wiem, że lambda() -> square() nie zadziała, ponieważ square musi zostać przekazana wartość. Chciałem utworzyć tablicę 100 Runnable s, z których każda ma następny argument dla square, ale nadal metoda run() niczego nie zwraca. Krótko mówiąc, jak wyglądałaby metoda, która ocenia inną funkcję podaną jako argument, np. square przy różnych wartościach x i zwraca tablicę wyników? Ponadto, najlepiej nie chcę zaczynać żadnych nowych wątków, chociaż jeśli jest to jedyny sposób, w jaki można to osiągnąć, to jest w porządku. Wreszcie, nie chcę mieć potrzeby implementowania funkcji square (lub innej) w specjalny sposób (najlepiej).

Odpowiedz

1

Nadzieja to pomaga:

public int[][] fn2Array(Function<Integer, Integer> fn, int x) { 
    int[][] result = new int[x][2]; 
    for (int i; i < x; i++) { 
     result[i][0]=i+1; 
     result[i][1]=fn.apply(i+1); 
    } 
    return result; 
} 
+2

Rozważ "IntunaryOperator" zamiast "Function ", unika niepotrzebnego boksowania. – Tunaki

2

Mam nadzieję, że nie przeszkadza, jeśli nie używać Array, ale będę używać metody

public Map<Integer, Integer> lotsOfSquares(int limit) { 

    return IntStream.rangeClosed(1,limit)       // Creates a stream of 1, 2, 3, ... limit 
        .boxed()          // Boxes int to Integer. 
        .collect(Collectors.toMap(i -> i,    // Collects the numbers, i->i generates the map key 
               i -> square(i)); // Generates the map value 
} 

square To daje mapę zawierającą {1=1, 2=4, 3=9, ... , 99=9801, 100=10000}.

Powinieneś prawdopodobnie dodać poprawność na limit.

Aktualizacja:

public <T> Map<Integer, T> lotsOfResults(int limit, Function<Integer, T> f) { 

    return IntStream.rangeClosed(1,limit)       
        .boxed()          
        .collect(Collectors.toMap(i -> i,    
               i -> f.apply(i));  
} 

Teraz można zadzwonić lotsOfResults(100, i -> square(i))

Zauważ, że T jest typem powrotu f - w przypadku, gdy znudzi kwadratury.

+0

Chciałbym przekazać kwadratowy jako argument. Tutaj za każdym razem musiałbym zmienić metodę, z której korzystam (na coś podobnego do grzechu, itd.), Więc jak miałbym argumentować jako kwadrat? –