2012-04-25 3 views
2

Я использую HashMap, в котором я использую ArrayList в качестве значения.Использование списка внутри карты (Java)

Как это:

Map<Movie, List<Grades>> gradedMovies = new HashMap(); 

Я пытаюсь создать метод, с помощью которого я мог бы перебирать значения, чтобы увидеть, если ключ (фильм) уже существует. Если это так, я хотел бы добавить новое значение (класс) в список, назначенный конкретному ключу (видео). Что-то вроде этого:

public void addGrade(Movie movie, Grade grade) { 
// stuff here } 

В конце концов я wan't, чтобы иметь возможность распечатать карту, которая будет отображать фильмы и его оценку после того, как они были добавлены к карте.

Как это делается? Или весь мой подход (с использованием Карты) полностью неправильный?

Спасибо за любую помощь. (Это домашняя работа)

+3

Нет ничего плохого в подходе, который я вижу. Что конкретно вы застряли? – jacobm

+0

Я не знаю, как добавлять градации для конкретного фильма, так как HashMaps (как я понял) не имеют индексов. – Mark

+1

Если это домашнее задание, я предлагаю вам представить какой-то код, на который мы можем смотреть, и предлагать улучшения, а не просто просить вас дать вам решение. – claesv

ответ

3

Я думаю, что вы на правильном пути, просто убедитесь, что ваш объект фильма реализует equals и hashCode, чтобы он мог работать как истинный ключ для хэш-карты.

Если вы хотите, чтобы довольно печатная версия реализовала только метод toString.

public void addGrade(Movie movie, Grade grade) { 
    if (!gradedMovies.containsKey(movie)) { 
     gradedMovies.put(movie, new ArrayList()); 
    } 
    gradedMovies.get(movie).add(grade); 
} 

надеюсь, что это поможет, приветствия!

+0

Спасибо, это то, что я искал. – Mark

+0

FYI, это то, что делает Multimap. http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html –

3

Вы можете использовать что-то вроде этого:

public void addGrade(Movie movie, Grade grade) { 
    if (!gradedMovies.containsKey(movie)) { 
     gradedMovies.put(movie, new ArrayList<Grade>()); 
    } 
    gradedMovies.get(movie).add(grade); 
} 

Вам необходимо переопределить метод equals

3

Я не знаю, почему вы ищете индекс особенно - в точку из Map что вы можете искать записи по их ключам.

Так как отправная точка, первая линия вашего метода addGrade может выглядеть

List<grades> grades = gradedMovies.get(movie); 

и вы можете с надеждой взять его оттуда. (Не забудьте посмотреть на documentation, чтобы посмотреть, что происходит, если карта не содержит данный фильм еще ...)

+0

Хорошо, я не совсем понял, как использовать ключи. Благодарю. – Mark

1
public void addGrade(Movie movie, Grade grade) { 

boolean found = false; 
for(Movie m : gradedMovies.keyset()) { 
    // compare the movies 
    if(/* match on movies */) { 
     gradedMovies.get(m).add(grade); 
     found = true; 
    } 
} 
if(!found) { 
    gradedMovies.put(movie, new ArrayList().add(grade)); 
} 
} 
+0

В чем смысл итерации вместо использования Map.get? Это просто больше кода и медленнее. – Pablo

1
gradedMovies.containsKey(movie); 

    for(Map.Entry<Movie,List<Grades>> entry : gradedMovies.entrySet()){ 
      Movie key = entry.getKey(); 
     } 
+0

Итак, как он должен использовать этот код? – Pablo

2

Я мог бы перебирать значения, чтобы увидеть, если ключ (фильм) уже существует

Вам не нужно проходить через карту, просто позвоните gradedMovies.containsKey(movieToCheck).

Обратите внимание, что при использовании Movie в качестве ключа вы должны обеспечить разумную реализацию equals() и hashCode().

2

У вас все в порядке!но вы должны рассмотреть пару вещей:

При нахождении значения на карте объект вашего фильма должен переопределить равен и hashChode. Java всегда будет использовать метод equals для сравнения, в основном, когда речь идет о автоматических (например, проверка того, содержит ли список элемент или в этом случае, если значение ключа равно заданному). Помните, что equals определяет уникальность элемента, поэтому вы должны провести сравнение на основе уникального уникального атрибута, такого как идентификационный номер или (для этого случая) его имя.

Для того, чтобы напечатать карту, итерацию над Keyset, либо вручную (расширение «для» петли) или с помощью итератора (который может быть получен непосредственно с помощью метода .iterator()). Для каждого фильма вы печатаете список оценок аналогичным образом.

Я не знаю, знакомы ли вы со строковой печатью, но некоторые специальные комбинации символов могут быть добавлены в строку, чтобы придать ей какое-то форматирование. Например:

  • \ п будет вставить разрыв строки
  • \ т является табуляцией

Надеется, что это помогает удалить некоторые сомнения. Удачи!.

+0

Спасибо за советы! – Mark

+0

@Mark Без проблем :). Я забыл упомянуть, что, как и фильмы, Grades также должен реализовывать equals и hashCode, если вы хотите убедиться, что класс добавлен только один раз в список. Equals позволяет использовать вызов типа 'gradeList.contains (grade)'. – Gamb

1

Проверьте Guava Multimap. Это именно то, что он делает.

private Multimap<Movie, Grade> map = ArrayListMultimap.create(); 

public void addGrade(Movie movie, Grade grade){ 
    map.put(movie, grade); 
} 

Он позаботится о создании списка для вас.

Смежные вопросы