Domanda

Ho bisogno di un mappa funzione. C'è qualcosa di simile in Java già?

(Per coloro che si chiedono: Io naturalmente sapere come implementare questa funzione banale me stesso ...)

È stato utile?

Soluzione

Non v'è alcuna nozione di una funzione nel JDK come di Java 6.

Guava ha un interfaccia Funzione e anche se il
Collections2.transform(Collection<E>, Function<E,E2>)
metodo fornisce le funzionalità desiderate.

Esempio:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

Output:

[a, 14, 1e, 28, 32]

In questi giorni, con Java 8, v'è in realtà una funzione di mappa, così probabilmente sarei scrivere il codice in modo più conciso:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);

Altri suggerimenti

Dato che Java 8, ci sono alcune opzioni standard per fare questo in JDK:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

java.util.Collection.stream() e java.util.stream.Collectors.toList() .

C'è una meravigliosa libreria chiamata Funzionale Java che gestisce molte delle cose che ci si vuole Java per avere, ma non lo fa. Poi di nuovo, c'è anche questa lingua meravigliosa Scala che fa tutto Java avrebbe dovuto fare, ma non si pur essendo compatibile con qualsiasi cosa scritta per la JVM.

essere molto attenti con Collections2.transform() da guava. più grande vantaggio di questo metodo è anche il suo più grande pericolo:. la sua pigrizia

Guardate la documentazione di Lists.transform(), che a mio avviso vale anche per Collections2.transform():

  

La funzione viene applicata pigramente, invocato quando necessario. Ciò è necessario   per la lista restituita essere una visione, ma significa che la funzione   sarà applicata molte volte per operazioni di massa come   List.contains (java.lang.Object) e List.hashCode (). Per questo a   buone prestazioni, funzione dovrebbe essere veloce. Per evitare di valutazione pigra quando   l'elenco restituito non ha bisogno di essere una visione, copiare l'elenco restituito   in un nuovo elenco di tua scelta.

Anche nella documentazione di Collections2.transform() accennano si ottiene una visione dal vivo, che il cambiamento nella lista di origine influisce sulla lista trasformato. Questo tipo di comportamento può portare a problemi difficili da pista se lo sviluppatore non si rende conto del modo in cui funziona.

Se si vuole una "mappa" più classico, che verrà eseguito una sola volta e una sola volta, allora si sta meglio con FluentIterable , anche da Guava, che ha un funzionamento che è molto più semplice. Ecco l'esempio di Google per esso:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform() qui è il metodo mappa. Esso utilizza la stessa funzione di <> "callback" come Collections.transform(). La lista che si ottiene indietro è di sola lettura, però, l'uso copyInto() per ottenere una lista di lettura-scrittura.

In caso contrario, naturalmente, quando java8 esce con lambda, questo sarà obsoleto.

Questo è un altro lib funzionale, con il quale è possibile utilizzare la mappa: http://code.google.com / p / totallylazy /

sequence(1, 2).map(toString); // lazily returns "1", "2"

Anche se è una vecchia questione vorrei mostrare un'altra soluzione:

Basta definire il proprio funzionamento con generici Java e Java 8 flussi:

public static <S, T> List<T> mapAll(Collection<S> collection, Function<S, T> mapper) {
   return collection.stream().map(mapper).collect(Collectors.toList());
}

Che è possibile scrivere codice in questo modo:

List<String> hex = mapAll(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top