2

Help me with this

 Movie{
    int id;
    String title;
 }

 List<Movie> movies = new ArrayList<Movie>();
 Movie movie1 = new Movie(1,"movie1");
 Movie movie2 = new Movie(2,"movie2");
 Movie movie3 = new Movie(1,"movie3");
 Movie movie4 = new Movie(2,"movie4");
 movies.add(movie1);  movies.add(movie2);  movies.add(movie3);  movies.add(movie4); 

Now I have a list of movies including all 4 of above.

 (movies1,movies2,movies3,movies4)

But I want my list of movies contain only the last movies added among the ones that have the same Id which is :

  (movies3,movies4);

Update : Thank @LeffeBrune for the answer but now if I want two or more fields, not just one. What should I do?

  Movie{
     int id; String title ; String plot;
  }
  for example for both id and title field.
    (1,"title1","plot1"),(2,"title2","plot2"),(1,"title3","plot3"),(1,"title1","plot4")

   will become
    (2,"title2","plot2"),(1,"title3","plot3"),(1,"title1","plot4"),

Based on LeffeBrune's answer, Should I put the whole movie object as key and override an equal method.

4
  • Do you want to remove movie1 and movie3 from movies itself, or just return a list of movies that has id=2? Your question indicates you want them removed, but then what is the point of adding them in the first place if we're going to never need them again? Commented Nov 5, 2014 at 15:52
  • 1
    I assume you meant your list to be {movie3, movie4} because those are the two movies with distinct IDs added last. Commented Nov 5, 2014 at 15:55
  • @LeffeBrune yes, typo mistake, sorry! Commented Nov 5, 2014 at 16:00
  • @Compass I added them just for the example, actually I'm gonna get the list from somewhere else. Commented Nov 5, 2014 at 16:02

2 Answers 2

7

You need to use a right data structure for this. In this case a map will work:

Map<Integer, Movie> movies = new HashMap<>();
Movie movie1 = new Movie(1,"movie1");
Movie movie2 = new Movie(2,"movie2");
Movie movie3 = new Movie(1,"movie3");
Movie movie4 = new Movie(2,"movie4");
movies.put(movie1.id, movie1);
movies.put(movie2.id, movie2);
movies.put(movie3.id, movie3);
movies.put(movie4.id, movie4);

Now the map contains { movie3, movie4 } or the last added movies with that ID.

If you want to use "composite keys" where integer ID and title identify the movie you need to either use a more complicated data structure or resort to hacks. One easy way to create a composite key is to concatenate fields in it into a string and then use that string as a key in your map:

import java.util.HashMap;
import java.util.Map;

class Movies {
  static class Movie {
    int id;
    String title;
    String plot;

    Movie(int id, String title, String plot) {
      this.id = id;
      this.title = title;
      this.plot = plot;
    }

    @Override
    public String toString() {
      return String.format("{ %d, %s => %s }", id, title, plot);
    }
  }

  public static void main(String[] args) {
    Map<String, Movie> movies = new HashMap<>();
    Movie movie1 = new Movie(1, "title1" ,"plot1");
    Movie movie2 = new Movie(2, "title2", "plot2");
    Movie movie3 = new Movie(1, "title3", "plot3");
    Movie movie4 = new Movie(1, "title1", "plot4");

    // Create composite key by combining id and title into a string. 
    movies.put(movie1.id + movie1.title, movie1);
    movies.put(movie2.id + movie2.title, movie2);
    movies.put(movie3.id + movie3.title, movie3);
    movies.put(movie4.id + movie4.title, movie4);

    for (Map.Entry<String, Movie> entry : movies.entrySet()) {
      System.out.printf(
          "Key: %s Value: %s%n", entry.getKey(), entry.getValue());
    }
  }
}

The proper way to implement such a key would require creating another object and overriding its equals and hashCode methods. This is way more advanced territory.

Sign up to request clarification or add additional context in comments.

2 Comments

Now if I want two or more fields, not one ? Should I put the whole movie object as key and override an equal method? See my update
The thing that uniquely identifies a movie is its ID. Keep using that as a key, and add fields for additional data to Movie class.
0

Don't use a list, use a Map. Then you can expoit the fact that maps usually only allow one value with agiven key.

Map<Integer, Movie> map = new HashMap<Integer, Movie>();

//for each movie:
Movie movie = new Movie(1,"movie1")
map.put(movie.id, movie.title)

Then map.values() will give you movie 3 and movie 4.

Other classic solution include: Overwrite Movie.equals() to compare ids, and then add them to a set. This will give the same behaviour. All though not sure if sets will keep the first or the last one - so you might have to reverse the order of iteration.

Use a Sorted List with a custom comparator to make a set ordered by id, and then iterate over it pulling out the last move that occurs with every id.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.