Reputation: 3
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
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
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
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
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
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