LoginSignup
3
3

More than 5 years have passed since last update.

Java8のStreamを使ったprimitive型二次元配列の型変更(mapping)

Last updated at Posted at 2015-07-06

前置き

学校の課題でよくある,基本的な行列演算をJavaのクラスで実装するアレに出会いました。何回やればいいんだ。

最初,息を吸うようにdouble[][]をコンストラクタの引数にとっていたのですが,
せっかくだからBigDecimal[][]にしたいなあ,と思い立った矢先エラー

WA
// double[][] を引数に取るコンストラクタからワンラインでthis(BigDecimal[][])に渡したい
BigDecimal[][] mat = Stream.of(new double[][]{
    { 2, 4, -3, 4 },
    { -5, 2, 1, 5 },
    { -3, 4, 2, -1 },
    { 4, 6, -7, -2 }
}).map(a -> Stream.of(a)
        .map(BigDecimal::new) // Cannot resolve constructor BigDecimal
        .toArray(BigDecimal[]::new)
).toArray(BigDecimal[][]::new);

んなバカな。
書き直してみたところ,.map(v -> new BigDecimal(v)) // Connot resolve constructor 'BigDecimal(double[])'
どうやらvの型がdouble[]みたい。んなバカな。

あまり,Streamのことについて勉強しなかったのが悪いのですが,
primitive型は扱いが特殊になるので,DoubleStreamを使わないといけないみたいですね。
なんで分かれているんだろうと思ったら,そのためか。

と,いうわけでDoubleStreamに直せばOK(mapもDoubleStream対応のmapToObjに変える)。

Accepted Code

AC
BigDecimal[][] mat = Stream.of(new double[][]{
    { 2, 4, -3, 4 },
    { -5, 2, 1, 5 },
    { -3, 4, 2, -1 },
    { 4, 6, -7, -2 }
}).map(a -> DoubleStream.of(a) // ココ
        .mapToObj(BigDecimal::new) // ココ
        .toArray(BigDecimal[]::new)
).toArray(BigDecimal[][]::new);

...コンパイルは通ったが。検証コード

Tester
System.out.println(Stream.of(mat)
        .map(a -> Stream.of(a)
                .collect(Collectors.mapping(b -> b.toString(),
                        Collectors.joining(", ", "\t{ ", " }"))
                )
        ).collect(Collectors.joining(",\n", "{\n", "\n}"))
);
output
{
    { 2, 4, -3, 4 },
    { -5, 2, 1, 5 },
    { -3, 4, 2, -1 },
    { 4, 6, -7, -2 }
}

やったぜ:punch:

息を吸うようにStreamが書けるようになりたいです
(2次元配列になるとすごく頭がこんがらがる)。
あと早くこんな学生気分未満のコード生成からおさらばしたい。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3