質問は、より一般的であるとに関連していない長所と短所の両方のスタイルの。質問がある、それは良い可読性と宣言型であるため、ループの代わりにストリームを使用することが可能である時はいつでも私が好む必要がありますか?
私はストリームとforループを使用しての長所と短所についての私の同僚と議論されました。私たちは、時間の90%でストリームを好むべきであると同意するが、私はそれがループの代わりに、ストリームのために使用することをお勧めしたときに、いくつかの例があると信じています。
たとえば、私は、要素のコレクションにいくつかの操作を実行するために必要とこれらの操作は、チェック例外を投げることができました。任意の要素の例外occurres場合は動作しの間に私は、私はそれのためにループを使用してtry / catchブロックでそれを包んだように、すべての実行をやめたいと思いました。結果は、私が代わりにストリームを使用する場合に比べて2倍以上のラインにかかったので、私の同僚が満たされていませんでした。私は(例チェックされない例外を投げるに変換する例外と静的メソッドを確認スロー独自のカスタム機能インタフェース作成することによって、それを書き直しここ)、そして最後に、それはこのように見えたが。
try {
Map<String, String> someResult= elements.stream()
.filter(throwingPredicateWrapper(element-> client.hasValue(element)))
.collect(
Collectors.toMap(Function.identity(),
throwingFunctionWrapper(element -> client.getValue(element))));
return someResult;
} catch (Exception e) {
LOGGER.error("Error while processing", e);
}
それは2時間以内にコードの行を取ったので、彼は幸せでした。
それは簡単な例であり、それはそれほど悪くは見えませんが、ここで旧ループは、私は信じている場合に対処するために、よりシンプルかつ迅速な方法です。我々はそれが可能であるどこでもストリームを使用する傾向があるべきでしょうか?
ジョシュア・ブロック、「効果的なJavaの」の著者は、優れている話の流れを使用するときに触れます。「使用は慎重ストリーム」の彼のセクションのために30:30の周りに見始めます。
これは主に基づいた意見ではあるが、彼はあなたがすぐにストリームにあなたの手続きループのすべてを回し始めるしたくないと主張するが、あなたは本当にバランスの取れたアプローチをしたいです。彼はそうすることが理解することはより困難であるコードを生成し、少なくとも一つの例の方法を提供します。彼はまた、手続き型以上の機能的な方法でそれを書くかどうか、多くの場合には正解がないことを主張し、それは文脈に依存している(と私はチームが役割を果たしている可能性があるcorporately行うことを決めたものを主張するだろう)。彼は、上の例でありGitHubのを、そして以下のすべての例には、彼のGitHubのリポジトリからです。
ここで彼は彼の反復アナグラム方法の提供例があり、
// Prints all large anagram groups in a dictionary iteratively (Page 204)
public class IterativeAnagrams {
public static void main(String[] args) throws IOException {
File dictionary = new File(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
Map<String, Set<String>> groups = new HashMap<>();
try (Scanner s = new Scanner(dictionary)) {
while (s.hasNext()) {
String word = s.next();
groups.computeIfAbsent(alphabetize(word),
(unused) -> new TreeSet<>()).add(word);
}
}
for (Set<String> group : groups.values())
if (group.size() >= minGroupSize)
System.out.println(group.size() + ": " + group);
}
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
}
そして、ここでは、Streamsを使用しています
// Overuse of streams - don't do this! (page 205)
public class StreamAnagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(
groupingBy(word -> word.chars().sorted()
.collect(StringBuilder::new,
(sb, c) -> sb.append((char) c),
StringBuilder::append).toString()))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.map(group -> group.size() + ": " + group)
.forEach(System.out::println);
}
}
}
彼は主張している、の両方を使用してバランスの取れた、第三のアプローチのために
// Tasteful use of streams enhances clarity and conciseness (Page 205)
public class HybridAnagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(groupingBy(word -> alphabetize(word)))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.forEach(g -> System.out.println(g.size() + ": " + g));
}
}
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
}