2011-10-12 20 views
11

Por ejemplo (y esto está muy simplificado), supongamos que tengo una clase para cada carta en una baraja de cartas ... p. una clase KingOfSpaces, una clase QueenOfSpades, una clase JackOfDiamonds, etc. Todas las cuales se extienden a Card. Puede haber varias instancias de KingOfSpaces.En Java, ¿cómo puedo verificar si una colección contiene una instancia de una clase específica?

Y tengo un ArrayList<Card>, con 5 objetos. ¿Cómo puedo verificar si ese ArrayList contiene al menos un AceOfDiamonds?

Respuesta

10

Comencemos señalando que el uso de clases para este tipo de diferenciación es casi seguro algo malo. Diría que probablemente necesites hacer que 'Card' sea un poco más inteligente (es decir, tener un método getSuit() y getOrdinal()).

Pero, si insistes en hacerlo de esa manera, itera la lista de arreglos (puedes buscar en Google eso, es algo muy básico) y compara cada entrada en la lista usando el operador instanceof.

Has etiquetado esta pregunta como que tiene que ver con 'reflexión', lo que no parece correcto. ¿Estás seguro de que no quisiste marcarlo como 'tarea'?

OK - qué diablos, aquí está el código:

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

pero por favor no configurar la jerarquía de clases de esa manera - que es horrible diseño.

+0

Estoy seguro de que no es tarea ... Terminé mi carrera hace 5 años :) Supongo que eso es lo que estaba buscando. Estaba pensando que podría haber algo más sucinto como Arrays.containsInstanceOf (hand, AceOfDiamonds.class), pero supongo que no. La razón más profunda por la que lo hago así es porque las cartas, en lugar de ser como cartas, son más parecidas a las cartas de Magic: The Gathering, donde cada carta tiene una habilidad especial que modifica la "tabla" en algunas camino. Y al igual que Magic, puede ser necesario agregar nuevas tarjetas más tarde. –

4

Pruebe el operador instanceof:

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

Puede utilizar siguiente código:

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' incluye el nombre del paquete, por ejemplo: 'java.lang.String'

+1

este enfoque general funcionará (algo así como), pero es terriblemente ineficiente. El operador de instanceof está ahí por una razón. Además, su implementación podría mejorarse significativamente al devolver true en lugar de establecer tag = true. –

+0

Realmente querrás tener cuidado con este método.No tiene sentido la seguridad tipográfica, podría estar teniendo un mal rendimiento al no usar iteradores, y no puedo estar seguro de qué sucederá con el método getName() de la Clase. Creo que los otros enfoques enumerados son un poco más claros. –

+0

@KevinDay mientras tiene razón getclass mismo es ridículo establecer la etiqueta es mejor que regresar de varios lugares. – Shahzeb

4

@Daniel Pereira responde la pregunta como se le pidió. Me gustaría proponer que lo que realmente quieres es un enum.

Ejemplos:

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

En segundo lugar eso. Una enumeración es la estructura de datos apropiada para suites de tarjetas, o cualquier conjunto ordenado realmente. –

0

Comprobación del tipo de un objeto rompe esencialmente diversos principios orientados a objetos. La pregunta que quizás quiera responder es qué va a hacer una vez que encuentre ese tipo de objeto.

La acción a realizar sería el verbo que debe modelarse para cada tipo. Por ejemplo, en un juego de Solitario cuando haces clic en una carta puedes ponerla en la pila de la derecha si es un As. De modo que esa capacidad, ya sea que una carta pueda aterrizar en la pila, está determinada por el objeto en sí, ya que conoce su identidad. Así que, en esencia, debe implementar un método deal() para cada tarjeta y, en función de su objeto, sabe cómo debe implementarse deal() para su instancia. Al hacerlo fuera del objeto (y verificando el tipo) esencialmente has roto la encapsulación.

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

También podría explicar su respuesta para que sea útil para los futuros lectores. – Prudhvi

Cuestiones relacionadas