Search code examples
javaobjectcollectionssethashset

How to check if a set of object contains object with a particular attribute


Please look at the do while loop, I think the comment is self explanatory. I want to check if the set contains all the cards having symbol a,b,c,d (implementing it with help of array or anything else).

public class Experiment2_1 {
    
    public class Card {
        char symbol;
        int number;
    }
    
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        Set<Card> CardSet=new HashSet<>();
        char[] array= {'a','b','c','d'};        

        do {
            Card card=new Experiment2_1().new Card();           
            System.out.println("\nEnter a card Symbol: ");
            card.symbol=sc.next().charAt(0);
            System.out.println("\nEnter card number: ");
            card.number=sc.nextInt();
            CardSet.add(card);      
        } while(!CardSet.contains(array) /*The all elements a,b,c,d (of the array) are not present as symbol of cards. All four cards Found?*/);
        
        System.out.println("All four cards were found");
        sc.close();
    }
}

Solution

  • There are several issues related to you Card class and its usage:

    • Don't break Encapsulation, use access modifiers to protect class members, and getters to expose information. Make use of parameterized constructors and void using setters when you don't need them.

    • As the rule of thumb, when you're storing instances of a class in a hash-based collection, your class should have a proper implementation of the equals/hashCode contact.

    • To avoid creating the instance of the enclosing class, you can mark nested class Card as static.

    That's how class Card might look like:

    public static class Card {
        private char symbol;
        private int number;
        
        public Card(char symbol, int number) {
            this.symbol = symbol;
            this.number = number;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Card card = (Card) o;
            return symbol == card.symbol && number == card.number;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(symbol, number);
        }
    
        // getters, etc.
    }
    

    To find out whether all characters 'a','b','c','d' have been used as attributes of Card instances, you can create a Set containing those characters and track all symbols used in your cards by storing them into another set of characters.

    At the beginning of each iteration, you can verify if the set of symbols contains all the required characters or not using method Set.containsAll().

    Set<Card> cards = new HashSet<>();
            
    Set<Character> symbols = Set.of('a', 'b', 'c', 'd');
    Set<Character> symbolsSeen = new HashSet<>();
            
    while (!symbolsSeen.containsAll(symbols)) {
                
        System.out.println("\nEnter a card Symbol: ");
        char symbol = sc.next().charAt(0);
        System.out.println("\nEnter card number: ");
        int number = sc.nextInt();
                
        Card card = new Card(symbol, number);
        cards.add(card);
        symbolsSeen.add(symbol);
    }