2016-02-21 16 views
5

Come eseguire l'operazione Scala in basso per trovare il carattere più frequente in una stringa in java 8?Operazione di piegatura in Scala Vs Java 8

val tst = "Scala is awesomestttttts" 
val op = tst.foldLeft(Map[Char,Int]())((a,b) => { 
    a+(b -> ((a.getOrElse(b, 0))+1)) 
    }).maxBy(f => f._2) 

Qui l'uscita è

(Char, Int) = (t,6) 

sono stato in grado di ottenere un flusso di caratteri in Java 8 in questo modo:

Stream<Character> sch = tst.chars().mapToObj(i -> (char)i); 

ma non in grado di capire che cosa è la piega/l'alternativa foldLeft/foldRight abbiamo Java 8

Qualcuno può aiutarmi?

risposta

8

Qualcosa di simile sembra corrispondere con il codice Scala che hai fornito (se ho capito bene):

String tst = "Java is awesomestttttts"; 
Optional<Map.Entry<Character, Long>> max = 
    tst.chars() 
     .mapToObj(i -> (char) i) 
     .collect(Collectors.groupingBy(Function.identity(), 
             Collectors.counting())) 
     .entrySet() 
     .stream() 
     .max(Comparator.comparing(Map.Entry::getValue)); 
System.out.println(max.orElse(null)); 
+1

'System.out.println (Collections.max (tst.chars() .boxed() .collect (Collectors.groupingBy (i -> (char) (int) i, Collectors.counting())). entrySet(), Map.Entry.comparingByValue())) ' – Holger

+0

@Holger Quello non viene compilato in intellij 15 –

+1

@Federico Peralta Schaffner: quando lo copio dal mio commento, non funziona neanche, perché in qualche modo, un [ 'U + 200C'] (http://www.fileformat.info/info/unicode/char/200c/index.htm) [' U + 200B'] (http://www.fileformat.info/info/ unicode/char/200B/index.htm) la sequenza si è inserita tra '(' e ')' di 'emptySet()', invisibile ma causa errori del compilatore. Dopo aver rimosso questi due caratteri illegali, si compila bene con Netbeans e javac. – Holger

8

Se non ti dispiace utilizzando una libreria di terze parti Eclipse Collections ha un tipo che possono Bag tieni traccia dei conteggi dei personaggi. Ho fornito due esempi qui sotto che usano Borse. Purtroppo non è disponibile lo maxByOccurrences disponibile oggi allo Bag, ma lo stesso risultato può essere ottenuto utilizzando topOccurrences(1) che è disponibile. Puoi anche usare forEachWithOccurrences per trovare il massimo ma sarà un po 'più di codice.

Nell'esempio seguente viene utilizzato uno CharAdapter, anch'esso incluso nelle raccolte Eclipse.

MutableBag<Character> characters = 
    CharAdapter.adapt("Scala is awesomestttttts") 
     .collect(Character::toLowerCase) 
     .toBag(); 
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2); 

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0)); 
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1)); 

Il secondo esempio utilizza il metodo chars() accessibile String che restituisca un IntStream. Ci si sente un po 'imbarazzante che qualcosa chiamato caratteri() non restituisce un CharStream, ma questo è perché CharStream non è disponibile in JDK 8.

MutableBag<Character> characters = 
    "Scala is awesomestttttts" 
     .toLowerCase() 
     .chars() 
     .mapToObj(i -> (char) i) 
     .collect(Collectors.toCollection(Bags.mutable::empty)); 
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2); 

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0)); 
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1)); 

In entrambi gli esempi, ho convertito i caratteri in minuscolo prima, quindi non c'è sono 5 occorrenze di "s". Se si desidera che le lettere maiuscole e minuscole siano distinte, è sufficiente rilasciare il codice minuscolo in entrambi gli esempi.

Nota: Sono un committer per le raccolte Eclipse.

0

Ecco il campione dalla Corrente in AbacusUtil:

String str = "Scala is awesomestttttts"; 
CharStream.from(str).boxed().groupBy(t -> t, Collectors.counting()) 
      .max(Comparator.comparing(Map.Entry::getValue)).get(); 

ma penso che il modo più semplice per Multiset:

CharStream.from(str).toMultiset().maxOccurrences().get();