🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

701閲覧

JavaでMap<Integer, Map<Integer, List<Data>>>⇒Map<Integer, Map<Integer, Data[]>>への変換を短く記述できないか

longcat

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2021/03/03 09:55

編集2021/03/03 11:02

知りたいこと

JavaでMap<Integer, Map<Integer, List<Data>>>からMap<Integer, Map<Integer, Data[]>>に変換したい。
Listが配列に変わるだけで要素自体は同じ。Dataの部分は何でもよいが適当なクラス。
自分でも変換すること自体はできているが、streamAPIを駆使するなどしてより短く簡潔に記述できる良いやり方があれば知りたい。

自分が書いたコード

Java

1 static Map<Integer, Map<Integer, Data[]>> toArrayMap( 2 Map<Integer, Map<Integer, List<Data>>> listMap) { 3 4 Map<Integer, Map<Integer, Data[]>> arrayMap = new HashMap<>(); 5 6 listMap.entrySet().forEach(e1 -> { 7 Map<Integer, Data[]> innerMap = new HashMap<>(); 8 e1.getValue().entrySet().forEach(e2 -> { 9 innerMap.put(e2.getKey(), e2.getValue().toArray(new Data[e2.getValue().size()])); 10 }); 11 arrayMap.put(e1.getKey(), innerMap); 12 }); 13 14 return arrayMap; 15 16 }

###補足情報
JDKバージョン:jdk-8u202-windows-x64

質問をするまでの経緯・背景(追記)

(情報追加依頼により追記)

・なぜ変換しようとしているのか?
・元々Map<Integer, Map<Integer, Data[]>>で持っておくことができない理由はあるのか?
に対する補足説明です。

以下のような流れで生じた質問であり、
アプリケーション上、元々Map<Integer, Map<Integer, Data[]>>で持っておくことができない理由や、
変換をしなければいけない理由があるわけではありません。

既存プログラムのデータの持ち方を変えた場合に、処理速度やメモリ使用量がどのように変わるのかを調査したかった。

Listか配列かでどのように変化するかを確認する際に、
JavaでMap<Integer, Map<Integer, List<Data>>>⇒Map<Integer, Map<Integer, Data[]>>という変換を「実験として」行ってみる必要があった。

そのときに、自分では短い記述では書けず、「こんなにゴリゴリ書かないといけないのかな~?」という疑問が生まれた。

自分ではこの程度しか書けないけど、できる人はもっとスマート、エレガントに書けるのかもしれない。
ライブラリを使用する際などに、APIに合わせた変換をする必要は今後もあるかも知れないし、そういう知識は他の人にとっても有益かもしれない。
それだったら質問してみよう。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/03/03 09:58

「そもそもそういう形のデータを作る」ことができない背景があるのでしたら記載されたほうが良いかと思います。
longcat

2021/03/03 10:08

コメントありがとうございます。 すみません、「そもそもそういう形のデータを作る」とはどういうことを意味しているか少し分からなかったので、確認させてください。 わざわざ変換をしないといけない理由(はじめからMap<Integer, Map<Integer, Data[]>>にしておけばよいのに)という意味でしょうか?(おそらくこの意図かな、と思っています。) それとも、こういったデータを表現する1つのデータオブジェクトを作れないか? とか、独自のコレクションクラスを実装できないか?といったような意味でしょうか?
longcat

2021/03/03 11:04

意図通りの回答になっているかわかりませんが、質問をするまでの経緯・背景を追記しました。 わざわざ変換をしないといけないアプリケーション上の理由があるわけではなく、実験するために一時的に行った変換ではあったのですが、そこからより良い書き方は無いのかな?という疑問が生じたのが質問した理由になります。 もし意図と違っていましたら、お知らせください。
m.ts10806

2021/03/03 11:06

はい。仰る通り、データの変換 特に配列は全部回して全部見る必要があることのほうが多いです。 それなら「使いたい形でデータを最初から作ったらいいんじゃないか」と感じた次第です。 APIからそういう形のデータが来るから、とかないわけじゃないですからね。
guest

回答1

0

ベストアンサー

やり方はいろいろあると思いますが、自分であればvalueだけを変換した新しいMapを作るメソッド(transformValues)を作って、それを使うかなと思います。

Java

1public static Map<Integer, Map<Integer, Data[]>> toArrayMap(Map<Integer, Map<Integer, List<Data>>> listMap) { 2 return transformValues(listMap, map -> transformValues(map, list -> list.stream().toArray(Data[]::new))); 3} 4 5public static <S, T, U> Map<S, U> transformValues(Map<S, T> map, Function<T, U> transformer) { 6 return map.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> transformer.apply(e.getValue()))); 7}

ただあんまりやりすぎると、読む側が大変なので、この程度であればfor文でごりごり書いてしまったほうが、長期的にはよいかもしれません。

投稿2021/03/03 12:05

編集2021/03/03 23:56
neko_the_shadow

総合スコア2349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

longcat

2021/03/03 15:33

ありがとうございます。 こういうメソッド呼び出しを入れ子にしたやり方もできるのですね。 見たらわかりましたが、自分では思いつきませんでした。 たしかにおっしゃる通り、コードはすっきりしましたが、 パッと見のわかりやすさはなfor文の方が上かもしれませんね。
swordone

2021/03/03 19:43

List#toArrayでIntFunctionを受け取る形はないので、 list.toArray(Data[]::new)という書き方はできません。 list.stream().toArray(Data[]::new)ならできますが。
neko_the_shadow

2021/03/03 23:58

ご指摘ありがとうございます。Collection.toArray​(IntFunction<T[]>)はJDK11で追加されたAPIでした。Stream.toArray(IntFunction<T[]>)を利用するように修正しました。
swordone

2021/03/04 00:55

すみません。10までは確認したのですが、11まで見ていませんでした。
longcat

2021/03/04 01:10

補足ありがとうございます。 JDK8でlist.toArrayを使う場合は list.toArray(new Data[list.size()]) になりますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問