問題1
基本版
public class LoopBasic01 { public static void main(String[] args) { for (int i = 0; i < 10; i++) { System.out.println("Hello world!"); } } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional01 { public static void main(String[] args) { IntStream.range(0, 10).forEach(i -> System.out.println("Hello world!")); } }
問題2
基本版
public class LoopBasic02 { public static void main(String[] args) { for (int i = 6; i <= 10; i++) { System.out.println(i); } } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional02 { public static void main(String[] args) { IntStream.rangeClosed(6, 10).forEach(System.out::println); // System.out::println は i -> System.out.println(i) と同じ。 } }
問題3
基本版
public class LoopBasic03 { public static void main(String[] args) { int sum = 0; for (int i = 6; i <= 10; i++) { sum += i; } System.out.println(sum); } }
関数型版
iimport java.util.stream.IntStream; public class LoopFunctional03 { public static void main(String[] args) { int sum = IntStream.rangeClosed(6, 10).sum(); System.out.println(sum); } }
関数型版別実装(reduceを使用)
import java.util.stream.IntStream; public class LoopFunctional03_reduce { public static void main(String[] args) { int sum = IntStream.rangeClosed(6, 10).reduce((a, b) -> a + b).getAsInt(); System.out.println(sum); } }
問題4
基本版
public class LoopBasic04 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i = 0; i < data.length; i++) { sum += data[i]; } System.out.println(sum); } }
基本版別実装(拡張forを使用)
public class LoopBasic04_enhancedFor { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i : data) { sum += i; } System.out.println(sum); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional04 { public static void main(String[] args) { int sum = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10).sum(); System.out.println(sum); } }
なお、IntStream.of()は配列を受け取ることもできるので以下のようにも書けます:
import java.util.stream.IntStream; public class LoopFunctional04_fromArray { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = IntStream.of(data).sum(); System.out.println(sum); } }
関数型版別実装(reduceを使用)
import java.util.stream.IntStream; public class LoopFunctional04_reduce { public static void main(String[] args) { int sum = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .reduce((a, b) -> a + b).getAsInt(); System.out.println(sum); } }
問題5
基本版
public class LoopBasic05 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i = 0; i < data.length; i++) { sum += data[i]; } double ave = (double)sum / data.length; System.out.println(ave); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional05 { public static void main(String[] args) { double ave = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .average() .getAsDouble(); System.out.println(ave); } }
問題6
基本版
public class LoopBasic06 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int max = Integer.MIN_VALUE; for (int i = 0; i < data.length; i++) { if(max < data[i]) { max = data[i]; } } System.out.println(max); } }
基本版別実装(Integer#max()を使用)
public class LoopBasic06_another { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int max = Integer.MIN_VALUE; for (int i : data) { max = Integer.max(max, i); } System.out.println(max); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional06 { public static void main(String[] args) { int max = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .max() .getAsInt(); System.out.println(max); } }
関数型別実装(reduce使用)
reduceはこの例では int f(int a, int b) の形式を持つ関数オブジェクトを渡すことができ Integer::max を渡していますが、代わりに
(a, b) -> Integer.max(a, b)
あるいは
(a, b) -> a < b ? b : a
を渡しても動作は同じです:
import java.util.stream.IntStream; public class LoopFunctional06_reduce { public static void main(String[] args) { int max = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .reduce(Integer::max) // 代わりに (a, b) -> a < b ? b : a を入れても同じ .getAsInt(); System.out.println(max); } }
問題7
基本版
public class LoopBasic07 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i = 0; i < data.length; i++) { if(data[i] % 2 == 1) { sum += data[i]; } } System.out.println(sum); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional07 { public static void main(String[] args) { int sum = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .filter(i -> i % 2 == 1) // 奇数を抽出 .sum(); System.out.println(sum); } }
問題8
基本版
public class LoopBasic08 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int[] result = new int[data.length]; for (int i = 0; i < data.length; i++) { result[i] = data[i] * data[i]; } for (int i = 0; i < result.length; i++) { System.out.print(result[i] + " "); } } }
関数型版
下記の例でIntStreamからStream<Integer>に変換しているのは、IntStream#collect()は複雑なので、簡略化のためにStream<Integer>に変換しています:
import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class LoopFunctional08 { public static void main(String[] args) { List<Integer> result = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .map(i -> i * i) .boxed() // IntStream から Stream<Integer> に変換 .collect(Collectors.toList()); result.forEach(i -> System.out.print(i + " ")); } }
問題9
基本版
public class LoopBasic09 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i = 0; i < data.length; i++) { sum += data[i] * data[i]; } System.out.println(sum); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional09 { public static void main(String[] args) { int sum = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .map(i -> i * i) .sum(); System.out.println(sum); } }
問題10
基本版
public class LoopBasic10 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; int sum = 0; for (int i = 0; i < data.length; i++) { sum += data[i] * data[i]; } double ave = (double)sum / data.length; System.out.println(ave); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional10 { public static void main(String[] args) { double ave = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .map(i -> i * i) .average() .getAsDouble(); System.out.println(ave); } }
問題11
基本版
import java.util.Arrays; public class LoopBasic11 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; // 結果の配列の長さが不明だが、data.lengthを超えることはないので、 // 作業用配列としてはdata.lengthを長さとする。 int[] tempData = new int[data.length]; // 作業用の配列に偶数値を入れるときに使うインデックス int tempIndex = 0; for (int i = 0; i < data.length; i++) { if(data[i] % 2 == 0) { tempData[tempIndex++] = data[i]; } } // 結果の配列を作成する int[] result = Arrays.copyOf(tempData, tempIndex); for(int i = 0; i < result.length; i++) { System.out.print(result[i] + " "); } } }
関数型版
import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class LoopFunctional11 { public static void main(String[] args) { List<Integer> result = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) .filter(i -> i % 2 == 0) .boxed() // IntStream から Stream<Integer> に変換 .collect(Collectors.toList()); result.forEach(i -> System.out.print(i + " ")); } }
問題12
基本版
public class LoopBasic12 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; // int[] data = {2, 4, 6, 8, 10}; int max = Integer.MIN_VALUE; boolean maxExists = false; for (int i = 0; i < data.length; i++) { if(data[i] % 2 == 1) { if(max < data[i]) { max = data[i]; maxExists = true; } } } if(maxExists) { System.out.println(max); } else { System.out.println("None"); } } }
関数型版
import java.util.OptionalInt; import java.util.stream.IntStream; public class LoopFunctional12 { public static void main(String[] args) { OptionalInt maxOpt = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) // OptionalInt maxOpt = IntStream.of(2, 4, 6, 8, 10) .filter(i -> i % 2 == 1) .max(); if(maxOpt.isPresent()) { System.out.println(maxOpt.getAsInt()); } else { System.out.println("None"); } } }
問題13
基本版
public class LoopBasic13 { public static void main(String[] args) { int[] data = {4, 6, 3, 5, 1, 7, 2, 8, 9, 10}; // int[] data = {1, 3, 5, 7, 9}; boolean evenExists = false; for (int i = 0; i < data.length; i++) { if(data[i] % 2 == 0) { evenExists = true; break; } } System.out.println(evenExists); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional13 { public static void main(String[] args) { boolean evenExists = IntStream.of(4, 6, 3, 5, 1, 7, 2, 8, 9, 10) // boolean evenExists = IntStream.of(1, 3, 5, 7, 9) .anyMatch(i -> i % 2 == 0); System.out.println(evenExists); } }
問題14
基本版
public class LoopBasic14 { public static void main(String[] args) { int[] data = {1, 3, 5, 7, 9}; // int[] data = {10, 9, 8, 7, 6}; boolean isAllOdd = true; for (int i = 0; i < data.length; i++) { if(data[i] % 2 != 1) { isAllOdd = false; break; } } System.out.println(isAllOdd); } }
関数型版
import java.util.stream.IntStream; public class LoopFunctional14 { public static void main(String[] args) { boolean isAllOdd = IntStream.of(1, 3, 5, 7, 9) // boolean isAllOdd = IntStream.of(10, 9, 8, 7, 6) .allMatch(i -> i % 2 == 1); System.out.println(isAllOdd); } }
問題15
基本版
public class LoopBasic15 { public static void main(String[] args) { int[] result = new int[5]; for (int i = 1; i <= 5; i++) { result[i - 1] = i * 123; } for(int i = 0; i < result.length; i++) { System.out.println(result[i]); } } }
関数型版
import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class LoopFunctional15 { public static void main(String[] args) { List<Integer> result = IntStream.rangeClosed(1, 5) .mapToObj(i -> i * 123) .collect(Collectors.toList()); result.forEach(System.out::println); } }
問題16
基本版
import java.util.Arrays; public class LoopBasic16 { public static void main(String[] args) { int[] temp = new int[100]; int tempIndex = 0; for (int i = 1; i <= 100; i++) { if(i % 3 != 0 && i % 5 != 0) { temp[tempIndex++] = i; } } int[] result = Arrays.copyOf(temp, tempIndex); for(int i = 0; i < result.length; i++) { System.out.print(result[i] + " "); } } }
関数型版
import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class LoopFunctional16 { public static void main(String[] args) { List<Integer> result = IntStream.rangeClosed(1, 100) .filter(i -> i % 3 != 0 && i % 5 != 0) .boxed() // IntStreamをStream<Integer>に変換 .collect(Collectors.toList()); result.forEach(i -> System.out.print(i + " ")); } }
問題17
基本版
public class LoopBasic17 { public static void main(String[] args) { String[] data = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; int maxLength = Integer.MIN_VALUE; int maxIndex = -1; for (int i = 0; i < data.length; i++) { if(maxLength < data[i].length()) { maxLength = data[i].length(); maxIndex = i; } } System.out.println(data[maxIndex]); } }
関数型版
ここでのポイントはどのようにして文字列の長さを比較するかです。Streamインタフェースはmax()を持つのでこれに比較基準を渡してやればOK。
max()はComparator<T>オブジェクトを受け取りますが、考え方としては次のようになります。
比較対象s1, s2があり s1 > s2 なら 正の数、s1 = s2なら0、s1 < s2なら負の数を返せばよい。
このような比較関数は (s1, s2) -> s1.length() – s2.length() とすることで求まります:
import java.util.stream.Stream; public class LoopFunctional17 { public static void main(String[] args) { String maxString = Stream.of("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December") .max((s1, s2) -> s1.length() - s2.length()) .get(); System.out.println(maxString); } }