2010-10-26 10 views
8

Poszukuję prostego sposobu na zastosowanie metody wywołania zwrotnego do każdego elementu w tablicy String. Na przykład w PHP mogę utworzyć wszystkie elementy w tablicy w następujący sposób:Java: Apply Callback to Array Values ​​

$array = array_map('strtolower', $array); 

Czy istnieje prosty sposób osiągnięcia tego w Javie?

+0

Co robi ta linia? To nie jest dokładnie ekspresyjne. – skaffman

+0

@skaffman - funkcja strtolower() PHP zwraca ciąg znaków małych liter, podobnie jak Java .toLowerCase(). Powyższa funkcja stosuje (mapuje) funkcję strtolower() do każdego elementu w tablicy $, zwracając tablicę ze wszystkimi elementami małymi literami. – mellowsoon

Odpowiedz

3

Nie ma'S jedno-liner przy użyciu wbudowanych funkcji, ale z pewnością można dopasować funkcjonalność iteracji nad tablicy:

String[] arr = new String[...]; 

... 

for(int i = 0; i < arr.length; i++){ 
    arr[i] = arr[i].toLowerCase(); 
} 
+0

+1 Podczas gdy istnieją interesujące odpowiedzi na rozwiązanie pytania, czasami, szczególnie dla kogoś uczącego się nowego języka, proste i proste atuty sprytne. – Bill

+0

Muszę iść z tą odpowiedzią. Pozostałe odpowiedzi są świetnymi przykładami odwzorowania elementów tablicy, ale rozwiązania są znacznie bardziej skomplikowane niż prosta iteracja, którą starałem się uprościć. – mellowsoon

7

Po pierwsze, tablice obiektów w Javie są znacznie gorsze od List s, więc powinieneś naprawdę ich użyć, jeśli to możliwe. Możesz utworzyć widok String[] jako List<String> przy użyciu Arrays.asList.

Po drugie, Java nie ma jeszcze wyrażeń lambda ani odniesień do metod, więc nie ma łatwego sposobu, aby to zrobić ... i odwoływanie się do metody o nazwie jako String jest wysoce podatne na błędy i nie jest dobrym pomysłem.

Powiedział, Guava zapewnia pewne podstawowe elementy funkcjonalne, które pozwolą Ci robić to, co chcesz:

public static final Function<String, String> TO_LOWER = 
    new Function<String, String>() { 
     public String apply(String input) { 
     return input.toLowerCase(); 
     } 
    }; 

// returns a view of the input list with each string in all lower case 
public static List<String> toLower(List<String> strings) { 
    // transform in Guava is the functional "map" operation 
    return Lists.transform(strings, TO_LOWER); 
} 

przeciwieństwie tworząc nową tablicę lub List i kopiowanie małą wersję każdego String do niego, to robi nie powtarzaj elementów oryginalnego List po utworzeniu i wymaga bardzo mało pamięci.

Z Java 8, wyrażenia lambda i referencje metody powinny ostatecznie zostać dodane do Java wraz z metod rozszerzenie dla funkcji wyższego rzędu, takich jak map, czyniąc to znacznie łatwiejsze (coś takiego):

List<String> lowerCaseStrings = strings.map(String#toLowerCase); 
+0

Chcę przyjąć twoją odpowiedź, ponieważ chodzi o to, jak się spodziewałem. Ale człowiek ... To jedna potężna biblioteka, którą mogę dodać do mojego projektu tylko do jednego użytku. :/ – mellowsoon

+0

@mellowsoon: Zaufaj mi, istnieje wiele innych powodów, dla których warto używać Guava. To tylko jeden mały przykład. – ColinD

1

można użyć odbicie:

String[] map(java.lang.reflect.Method method, String[] array) { 
    String[] new_array = new String[array.length]; 
    for (int i = 0; i < array.length; i++) new_array[i] = (String)method.invoke(null, new Object[]{array[i]}); 
    return new_array; 
} 

Następnie wystarczy zadeklarować gdzieś metodę statyczną i uzyskać odwołanie do niej za pomocą interfejsu API Reflect.

+0

To irytujące, ponieważ trzeba tworzyć szczegółowe klasy dla tego rodzaju rzeczy, refleksja nie jest realnym wyborem. Konieczność korzystania z literek napisanych w sposób podatny na błędy dla nazw metod (które przerywają, jeśli zmieniona jest nazwa metody) oraz brak jakiegokolwiek bezpieczeństwa w odniesieniu do parametrów i typu zwracanej metody sprawiają, że jest to bardzo delikatne. – ColinD

+0

Nie bardziej kruchy niż kod PHP OP :) –

+0

Masz absolutną rację, ale na pewno nie jest to coś, co chciałbym zobaczyć emulowane w dowolnym miejscu. – ColinD