2015-09-11 12 views
10

単語リストのテキストファイルがあります。そのファイルから最小、最大、平均の単語長を取得したいと思います。私は、最大印刷し、期待どおりに動作しますラムダ式を使用して単語の平均長を取得する方法

System.out.println(readWords(filename) 
     .min(Comparator.comparing(s -> s.length())) 
     .get() 
     .length() 
); 
System.out.println(readWords(filename) 
     .max(Comparator.comparing(s -> s.length())) 
     .get() 
     .length() 
); 

をもminよテストのための私の主な方法で

public static Stream<String> readWords(String filename) { 
    try { 
     BufferedReader reader = new BufferedReader(new FileReader(filename)); 
     Stream<String> stringStream = reader.lines(); 
     return stringStream; 
    } catch (IOException exn) { 
     return Stream.<String>empty(); 
    } 
} 

私はストリーム方式を持っています。

質問:
それは私が最小値と最大値で行ったように単語の長さの平均値を取得することはできますか?どちらの場合も、はいまたはいいえ、それを行う方法(ラムダ式としてのみ)?

+0

.reduce(0、(i、c) - > c + i.length())を使用して行数で割ります。 –

+0

ヒント:あなたのファイルが本当に大きく、たくさんの行がある場合は、reduceの代わりにcollectを使用してください。 –

+0

@JoshuaKあなたの貢献にもお礼を言います。私は以下の答えを見つけました –

答えて

13

lines()メソッドは、単語ではなく行のストリームを取得します。あなたはStreamを持っていたら、単語を分割するラムダ式を供給、言葉で行を置き換えるためにflatMapを呼び出します。

Stream<String> stringStream = reader.lines().flatMap(line -> 
    Stream.of(line.split("\\s+")) 
); 

これはmaxminの実装を修正します。また、実装したい平均計算の正確さにも影響します。

平均を得るために、あなたはOptionalDoubleを返す、averageを呼び出し、その後、(IntStreamを生じる)その長さに単語のストリームをマッピングするmapToIntを呼び出すことができます。

System.out.println(readWords(filename) 
    .mapToInt(s -> s.length()) // or .mapToInt(String::length) 
    .average() 
    .getAsDouble()); 
+0

なぜ11であるべきですか? –

+0

これはうまく動作し、.flatMapなどに関するご意見をお待ちしております。 –

+3

'summaryStatistics()'について - https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream .html#summaryStatistics-- – ZhongYu

6

公式ドキュメントあなたは、おそらく1回のパスで最小、最大および平均値を取得するためにString::length

+0

あなたのコードがうまく動いています。私はストリーム入力のために他の答えを選択しましたが、あなたの答えも有効です。 –

+0

同じ理由でrgettmanの回答をアップしました:-)ありがとう –

7

使用IntSummaryStatisticsのようなメソッド参照を使用する必要があり、約reductions

System.out.println(readWords(filename) 
       .mapToInt(String::length) 
       .average() 
       .getAsDouble() 
); 

注意に基づいています。

IntSummaryStatistics summary = readWords(filename) 
    .collect(Collectors.summarizingInt(String::length)); 
System.out.format("min = %d, max = %d, average = %.2f%n", 
    summary.getMin(), summary.getMax(), summary.getAverage()); 
+1

ありがとうございます。盛り上がる –

関連する問題