前置き
学校の課題でよくある,基本的な行列演算を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 }
}
やったぜ
息を吸うようにStreamが書けるようになりたいです
(2次元配列になるとすごく頭がこんがらがる)。
あと早くこんな学生気分未満のコード生成からおさらばしたい。