2011-10-12 17 views
11

たとえば、(これは非常に単純化されていますが)、カードのデッキにあるすべてのカードのクラスがあるとします。 クラス、QueenOfSpadesクラス、JackOfDiamondsクラスなどがあり、そのすべてがCardに拡張されています。 KingOfSpacesのインスタンスが複数存在する可能性があります。Javaでは、コレクションに特定のクラスのインスタンスが含まれているかどうかを確認するにはどうすればよいですか?

そして私にはArrayList<Card>があり、その中に5つのオブジェクトがあります。 ArrayListに少なくとも1つのAceOfDiamondsが含まれているかどうかを確認するにはどうすればよいですか?

答えて

10

をこの種の差別化にクラスを使用することは、ほぼ確実に悪いことであることを指摘することから始めましょう。私はあなたがおそらく、 'カード'をもう少しインテリジェントにする必要があると言いたいと思います(つまり、getSuit()メソッドとgetOrdinal()メソッドを持つ)。

しかし、そうすることを強くお勧めするなら、配列リストを繰り返します(これはかなり基本的なことです)、instanceof演算子を使ってリストの各エントリを比較します。

この質問には、「反射」と関係があるとタグ付けされていますが、これは正しいとは思われません。 「宿題」にフラグを立てるつもりではないと確信していますか?

OK - 一体何が、ここではコードです:

List<Card> hand = ...; 
for(Card card : hand){ 
    if (card instanceof AceOfDiamonds) return true; 
} 

はなく、そのようなあなたのクラス階層を設定しないでください - それは恐ろしいデザインです。

+0

私はそれが宿題ではないと確信しています...私は5年前に私の学位を終えました:)私はそれが私が探していたものだと思います。私はArrays.containsInstanceOf(手、AceOfDiamonds.class)のようにもっと簡潔なものがあるかもしれないと思っていたが、そうは思わない。 カードのようなものではなく、カードがMagic:The Gatheringカードに似ているので、私がこれを好きなほど詳細な理由があるのは、各カードがいくつかの "テーブル"を変更する特別な能力を持っているからです方法。マジックのように、新しいカードを後で追加する必要があるかもしれません。 –

4

instanceof演算子を試してみてください。

if (myObject instanceof myType) { 
    System.out.println("myObject is an instance of myType!"); 
} 
1

あなたは以下のコードを使用することができます

private boolean findInstance(ArrayList items, String className) { 
    boolean tag = false; 
    for (int i = 0; i < items.size(); i++) { 
     if (items.get(i).getClass().getName().equals(className)) { 
      tag = true; 
      break; 
     } 
    } 
    return tag; 
} 

が 'className' は、たとえば、パッケージ名が含まれています 'はjava.lang.String型'

+1

この一般的なアプローチは(種類の)動作しますが、ひどく非効率です。 instanceof演算子には理由があります。また、tag = trueを設定する代わりにtrueを返すことで、実装を大幅に改善できます。 –

+0

あなたは本当にこの方法に慎重になりたいです。型の安全性はありません。イテレータを使用しないとパフォーマンスが低下する可能性があります。クラスのgetName()メソッドで何が起きるかはわかりません。リストされた他のアプローチはもう少し明確だと思います。 –

+0

@ KevinDayあなたが正しいgetclassの間にばかげた設定タグは複数の場所から戻ってきた方が良いです。 – Shahzeb

4

@ダニエル・ペレイラが質問に答えてくれます。あなたが本当に欲しいものがenumであることを提案したいと思います。

例:

enum Card { 
    KingOfSpades, 
    QueenOfSpades, 
    JackOfSpades, 
    // etc 
    AceOfDiamonds; 
} 

Card myCard = ...; 
if(myCard == Card.KingOfSpades) { 
    // stuff 
} 

Set<Card> cards = new EnumSet<Card>(Card.class); 
cards.add(...); 
if(cards.contains(myCard)) { 
    // stuff 
} 
+0

私はそれを二番目にします。列挙型は、カードスイート、または順序付けされたセットのための適切なデータ構造です。 –

0

は基本的にさまざまなオブジェクト指向の原則を破ったオブジェクトの種類を確認します。あなたが答えたいと思うかもしれない質問は、あなたがそのタイプのオブジェクトを見つけたら何をしようとしているかということです。

実行されるアクションは、各タイプに対してモデル化する必要がある動詞になります。たとえば、ソリティアのゲームでは、カードをクリックすると、それがAceの場合は右のスタックに置くことができます。そのため、カードがスタック上に着地できるかどうかは、その身元が分かっているので、オブジェクト自体によって決定されます。だから本質的には、各カードにdeal()メソッドを実装し、そのオブジェクトに基づいて、そのインスタンスに対してdeal()をどのように実装する必要があるかを知っている必要があります。オブジェクトの外側で(そしてタイプをチェックすることで)カプセル化が本質的に壊れてしまいます。

0
public static <E> boolean containsInstance(List<E> list, Class<? extends E> clazz) { 
    for (E e : list) { 

     try { 
      List<E> list2 = (List<E>) e; 
      for (E list21 : list2) { 
       System.out.println("<< ENCONTRO LISTA DENTRO DEL ARRAY DE OBJETOS >> "); 
       if (clazz.isInstance(list21)) { 
        return true; 
       } 
      } 
     } catch (Exception q) { 
      System.out.println("<< ENCONTRO OBJETO DENTRO DEL ARRAY DE OBJETOS >> "); 
      if (clazz.isInstance(e)) { 
       return true; 
      } 
      continue; 
     } 

    } 
    return false; 
} 
+2

将来の読者に役立つように答えを説明してください。 – Prudhvi

関連する問題