質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Q&A

解決済

3回答

19601閲覧

javaのMapの記述の仕方について

a0841_1974

総合スコア29

Java

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

0グッド

0クリップ

投稿2018/04/04 03:29

編集2018/04/05 09:20

いつもお世話になっております。
Javaの記述の仕方で分からない事があります。
ご存知の方がいらっしゃれば教えて頂けますでしょうか。

【ご質問】
以下のプログラムを記述すると
☆1で警告が表示されます。
警告を解消する為には、どのように修正すればよいのでしょうか。

JAVAのバージョンは1.8です。

public Map<Object,Object> getTantousya(){ String cacheKey = "tantousya:N"; Map<Object,Object> result = (Map)masterMap.get(cacheKey); ☆1 if(result == null){ result = key_value_service.getTantousya(); masterMap.put(cacheKey, result); } return result; }

(警告の内容)
☆1
型の安全性: 型 Map の式は、未検査の型変換を使用して Map<Object,Object> に準拠するようにする必要があります

(補足)
1.masterMapは、以下の様に宣言しております。

private final HashMap<String,Object> masterMap = new HashMap<>();

2.key_value_service.getTantousya()、以下の様に宣言しております。

public Map<Object,Object> getTantousya() ```  3.☆1の箇所を ```ここに言語を入力  Map<Object,Object> result = (Map<Object,Object>)masterMap.get(cacheKey); ```  に、変更すると、以下の警告が表示されます。 この行に複数マーカーがあります - Map は raw 型です。総称型 Map<K,V> への参照は、パラメーター化する必要があります - 型の安全性: Object から Map<Object,Object> への未検査キャスト 以上です。 よろしくお願いいたします。 (追記) Map<Object, Object>には、 以下のどちらかの戻り値を設定いたします。 ```ここに言語を入力 public Map<Object,Object> getQuerykeyValue(Integer renban){ List<KeyValue> list = keyValueMapper.querykeyValue(renban); Map<Object,Object> result = new HashMap<>(); for(int i=0;i<list.size();i++){ KeyValue keyvalue = (KeyValue)list.get(i); result.put(keyvalue.getKey(), keyvalue.getValue()); } return result; } public Map<Object,Object> getQuerykeyValueInteger(Integer renban){ List<KeyValue> list = keyValueMapper.querykeyValueInteger(renban); Map<Object,Object> result = new HashMap<>(); for(int i=0;i<list.size();i++){ KeyValue keyvalue = (KeyValue)list.get(i); result.put(keyvalue.getKey(), keyvalue.getValue()); } return result; } 【KeyValue】 public class KeyValue implements Serializable { static final long serialVersionUID = 1L; private Object key; private Object value; getter/setter } 【querykeyValueで実施するSQL】 <select id="querykeyValue" resultType="KeyValue"> SELECT key AS "key", value AS "value" FROM key_value_tbl WHERE renban = #{renban} ORDER BY sort_no </select> 【querykeyValueIntegerで実施するSQL】 <resultMap id="ResultMapInteger" type="KeyValue"> <result property="key" column="key" javaType="Integer" /> <result property="value" column="value" javaType="String" /> </resultMap> <select id="querykeyValueInteger" resultMap="ResultMapInteger"> SELECT key AS "key", value AS "value" FROM key_value_tbl WHERE renban = #{renban} ORDER BY sort_no </select> 【key_value_tblテーブルの型】 key VARCHAR value VARCHAR

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

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

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

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

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

swordone

2018/04/04 03:58 編集

masterMapの値にはMap<Object, Object>型以外のモノが入っていますか?(masterMapの型をMap<String, Map<Object, Object>>として問題がないか?)
a0841_1974

2018/04/04 04:00

ご連絡ありがとうございます。masterMapの値にはMap<Object, Object>型以外のものは入りません。
guest

回答3

0

ベストアンサー

こういう警告ですね?(コンパイルオプション-Xlint:uncheckedを指定してます)

T.java:6: 警告:[unchecked] 無検査キャスト Map<Object,Object> result = (Map<Object, Object>)masterMap.get(cacheKey); //☆1 ^ 期待値: Map<Object,Object> 検出値: Object

これはObjectをMap<Object, Object>へダウンキャストしているためですが、コンパイラーはこのダウンキャストが安全かどうか判断できません。"tantousya:N"というキーの値が必ずMap<Object,Object>になっているはずというのは(キャストが問題ないというのは)論理全体を見渡せる人間のみが判断できることです。

この警告を消すには「論理的にこのダウンキャストが問題ないと判断してるので警告は不要ですよ」とコンパイラーに伝える必要があり、それは@SuppressWarningsアノテーションを用いるとできます。

Java

1public Map<Object,Object> getTantousya(){ 2 String cacheKey = "tantousya:N"; 3 @SuppressWarnings("unchecked") // これ 4 Map<Object,Object> result = (Map<Object, Object>)masterMap.get(cacheKey); //☆1 5 if (result == null) { 6 result = key_value_service.getTantousya(); 7 masterMap.put(cacheKey, result); 8 } 9 return result; 10}

追記:ちなみに型引数の指定なしでMap型の値をMap<Object,Object>型の変数へ代入するのは警告の対象になりますが、それは型引数も含めてきっちりキャストする必要があります。上のコードではその点も修正しています。

参考:
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/SuppressWarnings.html

投稿2018/04/04 04:43

編集2018/04/04 04:54
KSwordOfHaste

総合スコア18394

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

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

KSwordOfHaste

2018/04/04 04:49

ちょっと補足します。これはmasterMapの値はMap<Object,Object>以外に色んな型の値が格納されるという前提での回答です。 全ての値がMap<Object,Object>ならmasterMapの型はMap<String,Map<Object,Object>>とすべきですが、そうはできないんですよね?
a0841_1974

2018/04/05 04:33

今回は全ての値がMap<Object,Object>ですので、 masterMapの型を private final HashMap<String,Map<Object,Object>> masterMap = new HashMap<>(); としたら解決しました。 ありがとうございました。
KSwordOfHaste

2018/04/05 04:50

おっと意外な結末です・・・ そういうことならもちろんSuppressWarningsアノテーションは付けないのが正解になりますね。 なお、型引数としてMap<Object, Object>が妥当なのかも若干気になります。 少なくともMapのキーの型をObjectにするというのは普通は避けると思うのです。キーや値の型は本当は何か特定の型ではないのですか?
a0841_1974

2018/04/05 09:20

ご回答ありがとうございます。 基本的な事が分かっていないので、詳細に記述させて頂きます。 ※詳細は、質問の(追記)をご確認して頂けますでしょうか。 頂きましたご質問ですと、Keyには、Integer or Stringを設定しますが、 この状態でmasterMapの型を HashMap<String,Map<Object,Object>> とするのは、よろしくないでしょうか。
KSwordOfHaste

2018/04/05 09:51

querykeyValueとquerykeyValueIntegerを見る限りKeyはString型とすべきように見えます。KeyValueというクラスでなぜkeyがObject型になっているかわかりませんが・・・ひょっとしてquerykeyValueとquerykeyValueInteger以外にも用いる汎用のクラスなんでしょうか? プログラムの設計がよく見えませんが、例えば自分なら class KeyValue<KEYTYPE, VALUETYPE> { KEYTYPE key; VALUETYPE value; } のようにジェネリクスにするかも知れません。繰り返しになりますが、そうすべきかどうかはプログラムの設計次第なところがあります・・・
a0841_1974

2018/04/05 15:06

ご回答ありがとうございます。 KeyValueは汎用クラスの目的で作成しております。 今のところKeyにはInteger,String,Longが来ることを想定しております。
KSwordOfHaste

2018/04/05 15:47

04/05 18:51にコメントしましたように、KeyValueクラスの定義のしかたによってキーをObject型にせずにInteger,String,Longそれぞれとして扱うこともできますが・・・ 本質問の主題からはなれてしまいますし、コメント欄で話せるほど単純な話題でもないのでキーワードだけコメントしておきますと「generics, generic method」あたりになると思います。機会があればその辺りを掘り下げてみるとよいかと思います。
a0841_1974

2018/04/06 01:19

ご回答ありがとうございます。 ジェネリクスについて詳しく分かっていないので、調べてみます。 ありがとうございます。
guest

0

多少割愛しましたが、警告はなくなりました。

java

1 public Map<Object, Object> getTantousya() { 2 String cacheKey = "tantousya:N"; 3 Map<Object, Object> masterMap = new HashMap<>(); 4 Map<?, ?> result = (Map<?, ?>) masterMap.get(cacheKey); 5 return new HashMap<>(result); 6 }

ご参考までに
List<Object>とList<?>の違い

投稿2018/04/04 04:11

szk.

総合スコア1400

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

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

a0841_1974

2018/04/04 04:51

ご連絡ありがとうございます。 ご連絡頂きました方法で出来ましたが、以下の場合はどのように記述したらよいのでしょうか。 public Map<Object,Object> getTantousyaWithNULL(){ // キャッシュキー名を取得するデータ毎に設定する。 String cacheKey = "tantousya:NULL"; Map result = (Map)masterMap.get(cacheKey); if(result == null){ result = new HashMap(); result.put((Object)new Integer(-1), (Object)"(指定なし)"); result.putAll(key_value_service.getTantousya()); masterMap.put(cacheKey, result); } return result; }
guest

0

こうやな・w・

public static void main(String[] args) { Map<Object, Object> omap = new HashMap<>(); omap.put("a", "9"); Object map = omap; Map<? extends Object, ? extends Object> xmap = (Map<?, ?>) map; System.out.println(xmap.get("a")); }

map型じゃないケースを想定するとこうなる「

public static void main(String[] args) { Map<Object, Object> omap = new HashMap<>(); omap.put("a", "9"); // Map<Object,Object>#get を課程 Object map = omap; // 以下 説明ソース Map<? extends Object, ? extends Object> xmap; if (map instanceof Map) { // 設定時 xmap = (Map<?, ?>) map; } else { // 未設定時(任意の別のマップを設定するなりしてください) xmap = omap; } System.out.println(xmap); }

投稿2018/04/04 04:07

編集2018/04/04 05:04
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

a0841_1974

2018/04/04 04:52

ご連絡ありがとうございます。 ご連絡頂きました方法で出来ましたが、以下の場合はどのように記述したらよいのでしょうか。 public Map<Object,Object> getTantousyaWithNULL(){ // キャッシュキー名を取得するデータ毎に設定する。 String cacheKey = "tantousya:NULL"; Map result = (Map)masterMap.get(cacheKey); if(result == null){ result = new HashMap(); result.put((Object)new Integer(-1), (Object)"(指定なし)"); result.putAll(key_value_service.getTantousya()); masterMap.put(cacheKey, result); } return result; }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問