Perché le raccolte java non forniscono una funzione per l'indice del valore massimo?

5

Ho utilizzato Collections.max(list) per molti progetti, ma occasionalmente desidero trovare l' indice di quell'elemento massimo. Mi sento stupido scrivere una funzione per farlo da solo in ogni programma che scrivo.

Perché l'interfaccia Raccolte non fornisce un Collections.maxIndex(list) ?

    
posta Seth 28.09.2014 - 02:35
fonte

2 risposte

16

Sebbene ci possa essere esattamente un valore massimo in una raccolta, ci può essere più di elemento che rappresenta quel valore. E.g {1, 9, 2, 9, 0} ha valore massimo di 9 , rappresentato da entrambi gli elementi [1] e [3] .

Si noti che non tutte le raccolte supportano l'accesso all'indice; per esempio. un Set<Integer> può avere un massimo significativo ma l'accesso a un elemento per indice non ha senso in esso.

Anche se limitiamo il metodo a List , sarebbe un po 'difficile trovare un metodo per trovare indici del valore massimo che non è maldestro. È possibile restituire un elenco di indici, ma in tal caso si perderebbe il valore e in alcune raccolte, ad es. elenchi concatenati, l'accesso a un elemento per indice è lento. Poiché Java non ha una sintassi semplice per le tuple, devi restituire un tipo speciale di oggetto con .getValue() e .getIndices() .

Ma penso che un'operazione del genere non sia abbastanza comune per essere supportata nella libreria standard. Trovare un massimo è letteralmente 3-4 linee di codice, e il tracciamento dell'indice è di altre 1-2 righe, e non c'è molto spazio per sbagliare. Se lo fai molto, puoi inserirlo facilmente nella tua classe di utilità.

    
risposta data 28.09.2014 - 03:12
fonte
2

Dai un'occhiata a API di Java 8 Streams .

Link: link

(Disclaimer: non l'ho usato prima.)

Tuttavia, non esiste un'implementazione out-of-the-box di maxIndex . Per abilitarlo, qualcuno dovrà fornire una coppia primitiva ad alte prestazioni o un'implementazione di stream tupla per Java 8 Stream.

La ragione è questa. Funzionalmente parlando, maxIndex è:

  • Converti ciascun valore in una coppia (tupla di 2) come: (value, position)
  • Riduci lo stream come segue:
    • Confronta i due elementi, (value1, position1) con (value2, position2) ,
    • Mantieni l'oggetto con il valore più alto e copia lungo la sua posizione.
      • Vale a dire, return (item1.value > item2.value) ? item1 : item2;
    • Se è possibile un pareggio, è necessario un meccanismo di spareggio, come indicato nella risposta di 9000 . Non sarà più una riduzione rispetto alla tupla, ma diventerà una "raccolta di tuple (valore, posizione) tutte aventi lo stesso valore massimo".
      • Finché sarà implementato un meccanismo di spareggio, l'approccio descritto qui sarà ancora applicabile.
  • Al termine dell'operazione, restituisci item.value come valore massimo e item.position come indice massimo.
    • Come sottolineato dalla risposta di 9000 , a seconda del meccanismo di spareggio, potrebbero esserci più risultati.

Sfortunatamente, come molti sostenitori di Java hanno sottolineato, Java come una lingua sta vivendo da un'esplosione di felicità in classe, e ciò è dovuto alla limitazione del supporto dei generici Java. Di conseguenza, se hai bisogno di qualcosa non trovato nell'API Java, devi eseguire il rollover o trovare una libreria o toolbox che faccia.

    
risposta data 01.10.2014 - 00:50
fonte

Leggi altre domande sui tag