[解決済み] JavaにおけるHashMapオブジェクトとMapオブジェクトの違いは何ですか?
質問
私が作成する以下のマップの違いは何ですか(別の質問で、人々が一見同じように使っているように答えていたので、違うのか/どう違うのか気になります)。
HashMap<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();
解決方法は?
オブジェクトの間に違いはなく、あなたが持っているのは
HashMap<String, Object>
を、両方のケースで使用します。に違いがあります。
インターフェース
を持つオブジェクトです。最初のケースでは、インターフェイスは
HashMap<String, Object>
であるのに対し、後者は
Map<String, Object>
. しかし、根本的なオブジェクトは同じです。
を使用する利点は
Map<String, Object>
を使用するコードとの契約を破棄することなく、基礎となるオブジェクトを別の種類のマップに変更することができる点です。もし、このオブジェクトを
HashMap<String, Object>
そのため、基本的な実装を変更する場合は、契約を変更しなければなりません。
例 例えば、こんなクラスを書いたとします。
class Foo {
private HashMap<String, Object> things;
private HashMap<String, Object> moreThings;
protected HashMap<String, Object> getThings() {
return this.things;
}
protected HashMap<String, Object> getMoreThings() {
return this.moreThings;
}
public Foo() {
this.things = new HashMap<String, Object>();
this.moreThings = new HashMap<String, Object>();
}
// ...more...
}
このクラスは、string->objectのいくつかの内部マップを持ち、それを(アクセッサメソッドを通して)サブクラスと共有します。例えば、次のように書くとします。
HashMap
というのも、クラスを書くときにこの構造を使うのが適切だと思うからです。
その後、Maryはこのコードをサブクラス化したコードを書きます。彼女は
things
と
moreThings
ということで、当然ながら彼女はそれを共通のメソッドに置き、私が
getThings
/
getMoreThings
を定義しています。
class SpecialFoo extends Foo {
private void doSomething(HashMap<String, Object> t) {
// ...
}
public void whatever() {
this.doSomething(this.getThings());
this.doSomething(this.getMoreThings());
}
// ...more...
}
その後、本当は
TreeMap
ではなく
HashMap
で
Foo
. 更新する
Foo
を変更します。
HashMap
から
TreeMap
. 今すぐ
SpecialFoo
はもうコンパイルできないのです。
Foo
を提供すると言っていた。
HashMap
を提供していましたが、現在は
TreeMaps
の代わりに そこで、私たちは
SpecialFoo
このようなことは、コードベース全体に波及する可能性があります。
よっぽどの理由がない限り、私の実装では
HashMap
(と宣言しておけばよかったのです。
getThings
と
getMoreThings
を返すだけなので
Map<String, Object>
それ以上具体的に説明することはありません。実際、他のことをする正当な理由がない限りは
Foo
を宣言する必要がありそうです。
things
と
moreThings
として
Map
ではなく
HashMap
/
TreeMap
:
class Foo {
private Map<String, Object> things; // <== Changed
private Map<String, Object> moreThings; // <== Changed
protected Map<String, Object> getThings() { // <== Changed
return this.things;
}
protected Map<String, Object> getMoreThings() { // <== Changed
return this.moreThings;
}
public Foo() {
this.things = new HashMap<String, Object>();
this.moreThings = new HashMap<String, Object>();
}
// ...more...
}
今、私は
Map<String, Object>
実際のオブジェクトを作成するときだけ、具体的に説明します。
そうしていれば、メアリーはこうなっていたでしょう。
class SpecialFoo extends Foo {
private void doSomething(Map<String, Object> t) { // <== Changed
// ...
}
public void whatever() {
this.doSomething(this.getThings());
this.doSomething(this.getMoreThings());
}
}
...と変更
Foo
を使っても
SpecialFoo
はコンパイルを停止します。
インターフェース(と基底クラス)により、以下のことが明らかになります。
必要な分だけ
そのため、必要に応じて変更できるような柔軟性を保っています。一般に、参照はできるだけ基本的なものにしたいものです。もし、それが
HashMap
と呼ぶだけでよい。
Map
.
これは盲目的なルールではありませんが、一般的には
最も一般的なインターフェイスへのコーディング
は、より具体的なものに合わせてコーディングするよりも、より脆くなりそうです。もし私がそのことを覚えていたら、私は
Foo
でメアリーが失敗するように仕向けた
SpecialFoo
. もし
メアリー
を覚えていたのなら、たとえ私が失敗しても
Foo
でプライベートメソッドを宣言していたはずです。
Map
の代わりに
HashMap
と、私が変更した
Foo
のコントラクトは、彼女のコードに影響を与えなかったでしょう。
それができない場合もあるし、具体的に説明しなければならない場合もある。しかし、そうしなければならない理由がない限り、最も特殊性の低いインターフェイスを選ぶようにしましょう。
関連
-
コンストラクタの呼び出しは、コンストラクタのエラー理解の最初のステートメントである必要があります。
-
自動配線された依存性のインジェクションに失敗しました。
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] StringBuilderとStringBufferの違いについて
-
[解決済み] DTO、VO、POJO、JavaBeansの違い?
-
[解決済み] ConcurrentHashMapとCollections.synchronizedMap(Map)の違いは何ですか?
-
[解決済み】HashMap、LinkedHashMap、TreeMapの違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
エラー java.util.NoSuchElementException
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
java の例外が発生しました java
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
アクセス制限です。タイプ 'Application' は API ではありません。
-
JavaMailのメール送信が失敗するケースとその説明の分析
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
ブラウザでの大容量ファイルスライスアップロード(Javaサーバサイド実装)