Stiltinho
Stiltinho

Reputation: 3

Retrieving values from a map that contains sets of objects

Firstly, I'm not very good at this java lark, so bear with me...

I have a map where the keys are Strings representing the title of a film and the values are Sets of actors, represented by objects of class Actor which each have their own attributes.

What I want to do is iterate over the map, returning the film title and the actors in a meaningful way.

I've got the map iteration part but I can't figure out how to do the next loop which produces the values from the Set of Actors.

Here's what I have:

Map <String, Set> filmCollection = new HashMap<>();
Actor a1 = new Actor("Joe Smith", "20071977");
Actor a2 = new Actor("Kate Jones", "01011980");
Actor a3 = new Actor("Frank DeFrank", "02021945");
Set <Actor> s1 = new HashSet<>();
Set <Actor> s2 = new HashSet<>();
s1.add(a1);
s1.add(a2);
s2.add(a3);
s2.add(a1);
filmCollection.put("The Best Film", s1);
filmCollection.put("The Nearly Best Film", s2);

Set<String> collectionKeys = filmCollection.keySet();
for (String eachFilm : collectionKeys)
{
    System.out.println(eachFilm + " stars the actors ");
}

I know this is basic stuff and is probably very simple, but i'm learning and I've been searching and trying things all day - my head feels like it might explode soon! Any guidance would be appreciated.

Upvotes: 0

Views: 105

Answers (5)

Michael
Michael

Reputation: 44190

Your problem is that the key set does not contain any information about the actors. The key set just contains the keys.

You can loop over the map entries which are key -> value pairs. Once you have the set of actors, you can concatenate their names with String.join

for (Map.Entry<String, Set<Actor>> film : filmCollection.entrySet())
{
    // get all the names for this film (I would usually use streams for this, but 
    // they're a bit more advanced)
    Set<String> actorsNames = new HashSet<>();
    for (Actor actor : film.getValue())
    {
        actorsNames.add(actor.getName());
    }

    // concatenate the names with String.join
    System.out.println(
        film.getKey() + " stars the actors " + String.join(", ", actorsNames)
    );
}

You will also need to change the definition of your map to:

Map<String, Set<Actor>> filmCollection = new HashMap<>();

because this states that the set is a set of actors. Without this, it's just a set of objects.


Little bonus for how I'd do this with streams:

filmCollection.entrySet().stream()
    .map(film -> film.getKey() + " stars the actors "
        + film.getValue().stream().map(Actor::getName).collect(Collectors.joining(", "))
    )
    .forEach(System.out::println);

Upvotes: 0

Bilal EL CHAMI
Bilal EL CHAMI

Reputation: 414

So what you did is looping over the set of keys of the map. Since you have the keys, now you need to get the value of each key stored in the map. To do so, you have to call filmCollection.get(eachFilm).

Full code

Map <String, Set<Actor>> filmCollection = new HashMap<String, Set<Actor>>();
Actor a1 = new Actor("Joe Smith", "20071977");
Actor a2 = new Actor("Kate Jones", "01011980");
Actor a3 = new Actor("Frank DeFrank", "02021945");
Set <Actor> s1 = new HashSet<>();
Set <Actor> s2 = new HashSet<>();
s1.add(a1);
s1.add(a2);
s2.add(a3);
s2.add(a1);
filmCollection.put("The Best Film", s1);
filmCollection.put("The Nearly Best Film", s2);

Set<String> collectionKeys = filmCollection.keySet();
for (String eachFilm : collectionKeys)
{
    System.out.println(eachFilm + " stars the actors ");
    for (Actor actor : filmCollection.get(eachFilm)) {
        System.out.println(actor + ", ");
    }
}

Upvotes: 1

Shanu Gupta
Shanu Gupta

Reputation: 3807

There you go: Your filmCollection should be a Map<String, Set<Actor>>

Map<String, Set<Actor>> filmCollection = new HashMap<>();
Actor a1 = new Actor("Joe Smith", "20071977");
Actor a2 = new Actor("Kate Jones", "01011980");
Actor a3 = new Actor("Frank DeFrank", "02021945");
Set<Actor> s1 = new HashSet<>();
Set<Actor> s2 = new HashSet<>();
s1.add(a1);
s1.add(a2);
s2.add(a3);
s2.add(a1);
filmCollection.put("The Best Film", s1);
filmCollection.put("The Nearly Best Film", s2);

Set<String> collectionKeys = filmCollection.keySet();
for (String eachFilm : collectionKeys) {
    System.out.print(eachFilm + " stars the actors : ");
    for (Actor actor : filmCollection.get(eachFilm)) {
        System.out.print(" [ " + actor.name + " ] ");
    }
    System.out.println();

Sample output:

The Best Film stars the actors :  [ Kate Jones ]  [ Joe Smith ] 
The Nearly Best Film stars the actors :  [ Frank DeFrank ]  [ Joe Smith ] 

Upvotes: 0

xtratic
xtratic

Reputation: 4699

Since you are using both the film and actors then just iterate over the entries of your film-to-actors map, since the entries contains both the key and the value. Then, for each entry, print the name of the film (entry.getKey()) and get the set of actors (entry.getValue()) and print each one.

Map <String, Set<String>> filmCollection = new HashMap<>();
// ...
for (Map.Entry<String, Set<String>> entry : filmCollection.entrySet()){
    System.out.println(entry.key() + " stars the actors " + entry.value());
    // or
    for(String actor : entry.value()){
        System.out.println(actor);
    }
}

Upvotes: 0

HBo
HBo

Reputation: 633

If I understand you properly, you just lack a loop: the first one loops over the films, and you should have another one for their actors. Use entrySet instead of keySet if you need both key and value at the same time. I tweaked your code a little bit to show you what I mean:

    Map <String, Set<Actor>> filmCollection = new HashMap<>();
    Actor a1 = new Actor("Joe Smith", "20071977");
    Actor a2 = new Actor("Kate Jones", "01011980");
    Actor a3 = new Actor("Frank DeFrank", "02021945");
    Set <Actor> s1 = new HashSet<>();
    Set <Actor> s2 = new HashSet<>();
    s1.add(a1);
    s1.add(a2);
    s2.add(a3);
    s2.add(a1);
    filmCollection.put("The Best Film", s1);
    filmCollection.put("The Nearly Best Film", s2);

    for (Entry<String, Set<Actor>> eachFilm : filmCollection.entrySet()) {
        // The key -> a movie
        System.out.println(eachFilm.getKey() + " stars the actors "); 

        // The value -> the actors
        for (Actor actor : eachFilm.getValue()) {
         System.out.println(actor);
        }
    }

Upvotes: 0

Related Questions