2017-02-08 4 views
1

私は単語(プログラミング言語)を持つリストを持っており、アルファベットのどの文字がこれらの単語に存在するか把握し、合計文字列を合計したいこれらの単語の長さ、そして最後にこれらの単語に一致する最も長い文字列を返す1文字を返します。ここまで私が今まで持っていたものがあります。文字がある文字列の合計を返す - ストリームを使用する

これは、Javaストリームをよりよく理解しようとしている私の練習です。それは合計LISP、: "17 P" の文字 'P' の言葉のPHP、PythonやPerlで存在しているよう

私が期待する

package com.example; 

import org.junit.Test; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.function.Supplier; 
import java.util.stream.IntStream; 
import java.util.stream.Stream; 

public class DemoApplicationTests { 

    @Test 
    public void argh() { 

     List<String> list = new ArrayList<>(); 
     list.add("java"); 
     list.add("php"); 
     list.add("python"); 
     list.add("perl"); 
     list.add("c"); 
     list.add("lisp"); 
     list.add("c#"); 

     Supplier<Stream<String>> streamSupplier =() -> list.stream(); 
     IntStream.range('a', 'z').forEach(i -> { 
       int strlen = streamSupplier.get() 
        .filter(k -> { 
          char ch = (char) i; 
          return k.contains("" + ch); 
         } 
        ) 
        .map(s -> s.length()) 
        .mapToInt(Integer::new) 
        .sum(); 
       System.out.println((char) i + " : " + strlen); 
      } 
     ); 
    } 
} 

最終出力(結果は) のようなだけで何かでありますそれらの単語のみ最長の文字列を含む、

map<String,int> with the size of 1 

または何かであることが好ましく17

のStringLengthのを返します。

は、ここで私は「平野」Javaでそれを書かれているだろうかに関して、いくつかの擬似コードです:

int previousSum = 0; 
for (string ch in ('a' to 'z')) { 
    int stringlengthSum =  findallMatchesInListandSumStringlength(stringlist,ch); 
if (stringlengthSum > previousSum) { 
    previousSum = stringLengthSum; 
    longestCharacter = ch; 
} 
} 
System.out.println("The longest sum is: " + previousSum + " by the character: " + longestcharacter); 
+2

期待する出力は? – assylias

+0

この具体的な例で受け取りたい結果を記述できますか?あなたがしたいことははっきりしていません。 – Andremoniy

+1

私によく見える、あなたの質問は何ですか?おそらくこれはCodeReviewに適していますか? –

答えて

1

私は少し変更して、コードを最適化する必要がありました。 )

1この

2からでき収集マップであるためIntStreamStream<Integer>に変換)のペアを収集:

Map.Entry<Integer, Integer> max = IntStream.range('a', 'z').boxed().collect(Collectors.toMap(i -> i, i -> list.stream() 
     .filter(k -> k.contains("" + (char) i.intValue())) 
     .map(String::length) 
     .mapToInt(Integer::new) 
     .sum())) 
     .entrySet().stream() 
     .max((e1, e2) -> e1.getValue().compareTo(e2.getValue())).get(); 

System.out.println((char)max.getKey().intValue() + ":" + max.getValue()); 

変更がある:最終溶液はなりシンボルの整数値 - 単語>和をこのシンボル

と、少なくとも3)それは

+0

明らかに私はIntelliJ: ".max(Comparator.comparing(Map.Entry :: getValue))。get();によるとこれを行うことができます ありがとうございます! – OddBeck

+1

パフォーマンスを気にするならば、 '.filter(k - > k.indexOf(i)>) 'で' .filter(k - > k.contains( " = 0) 'と' .map(String :: length).mapToInt(Integer :: new) 'を' .mapToInt(String :: length) 'で置き換えます。より効率的な代替案がさらに簡単になることに注意してください。 '.max((e1、e2) - > e1.getValue()。compareTo(e2.getValue()))'は '.max(Map.Entry.comparingByValue())'に簡略化できます。 – Holger

1

あなたはかなり接近していた中で最大の要素を持つマップエントリを見つけると、あなたは基本的にストリームの順序を失っています。

class CharacterLengthSumResult implements Comparable<CharacterLengthSumResult> { 
     final char c; 
     final int sum; 

     CharacterLengthSumResult(char c, int sum) { 
      this.c = c; 
      this.sum = sum; 
     } 

     @Override 
     public int compareTo(CharacterLengthSumResult o) { 
      return Integer.compare(o.sum, sum); 
     } 
    } 

が次にストリーミングロジックは次のようになります:

は、専用のクラスを作成することができ、全体が少し楽に発注するようにするには

Optional<CharacterLengthSumResult> first = IntStream.range('a', 'z').mapToObj(i -> { 
      String c = ((char) i) + ""; 
      int sum = list.stream().filter(s -> s.contains(c)).mapToInt(String::length).sum(); 
      return new CharacterLengthSumResult((char)i, sum); 
     }).sorted().findFirst(); 

     if (first.isPresent()) { 
      System.out.println(first.get().c + " -> " + first.get().sum); 
     } 

あなたがマップとして全体のことをしたい場合は、コレクタでソートされたものを拡張することができます。

...sorted().collect(Collectors.toMap(s -> s.c, s -> s.sum)); 
+0

Hm ... overcomplicatedのように見える – Andremoniy

+0

@Andremoniy hmはマップエントリをハッキングする代わりにクリーンなコードのように見えます。 –

+0

*マップエントリのハッキング* ??? :)))hahahaあなたはハッキングをどこで見ますか?あなたがストリームを調理する方法を知らない場合、それが "ハッキング"であることを意味しない:)申し訳ありません – Andremoniy

関連する問題