Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over sets of sets

Tags:

java

iterator

set

I am attempting to write a program that iterates over a set of sets. In the example code below, I am getting an error that stating that iter.next() is of type object rather than a set of strings. I am having some other more mysterious issues with iterating over sets of sets as well. Any suggestions?

            Set<String> dogs= new HashSet<String>();
            dogs.add("Irish Setter");
            dogs.add("Poodle");
            dogs.add("Pug");
            dogs.add("Beagle");

            Set<String> cats = new HashSet<String>();
            cats.add("Himalayan");
            cats.add("Persian");

            Set<Set<String>> allAnimals = new HashSet<Set<String>>();                   
            allAnimals.add(cats);
            allAnimals.add(dogs);

            Iterator iter = allAnimals.iterator();            
            System.out.println(allAnimals.size());

            while (iter.hasNext()) 
            {
                System.out.println(iter.next().size());
            }   

A related question with the same setup (minus the loop).
The code fragment below results in a final output that includes tildes. But I don't want to change allAnimals as I go! How can I edit extension without affecting the larger set (allAnimals).

 for (Set<String> extension : allAnimals) 
                {
                    System.out.println("Set size: " + extension.size());
                    extension.add("~");     
                    System.out.println(extension);
                }   

                System.out.println(allAnimals);
like image 964
user2623054 Avatar asked Jul 26 '13 14:07

user2623054


4 Answers

Your allAnimals variable is of type Set<Set<String>>, however, when you ask its Iterator you "forget" the type information. According to the compiler, your iterator just contains Objects. Change the line where you get the Iterator to this

Iterator<Set<String>> iter = allAnimals.iterator();

and all should be fine.

like image 119
mthmulders Avatar answered Sep 22 '22 21:09

mthmulders


Use an enhanced for loop for traversing the sets, is easier than using an iterator:

for (Set<String> names : allAnimals) {
    System.out.println(names.size());
}

For example, to traverse all the animal's names:

for (Set<String> names : allAnimals) {
    for (String name : names) {
        System.out.println(name);
    }
}
like image 25
Óscar López Avatar answered Sep 21 '22 21:09

Óscar López


You do not mention the type on which your iterator is defined. So as far as it is concerned it expects an object as next.

like image 28
rocketboy Avatar answered Sep 21 '22 21:09

rocketboy


I would just use a (nested) foreach loop:

for(Set<String> animals : allAnimals) {
    int size = animals.size(); // if you want it
    for (String animal : animals) {
        // do something with the name
    }
}
like image 36
Bohemian Avatar answered Sep 18 '22 21:09

Bohemian