2015-12-17 3 views
1

Я хочу преобразовать список дат в карту, где месяц является ключом, а значения - это список дат с данным месяцем.Convert List <Date> to Map <месяц, список <Date>>

У меня есть следующий объект месяца, который в основном удерживает месяц и год, поэтому каждый месяц уникален.

public class Month implements Serializable, Comparable<Month> { 
     protected int year; 
     protected int month; 

     public Month(Date dag) { 
      Calendar cal = Calendar.getInstance(); 
      cal.setTime(dag); 
      this.month = cal.get(Calendar.MONTH)+1; //zerobased to onebased 
      this.year = cal.get(Calendar.YEAR); 
     } 

    } 

А теперь, учитывая список дат я пытаюсь сделать что-то вроде этого:

 public void addLedigeDage(List<Date> newLedigeDage) { 
     List<Date> datesPerMonth = new ArrayList<>(); 
     Calendar cal = Calendar.getInstance(); 
      for (Date date : newLedigeDage) { 
       cal.setTime(date); 
       Month month = new Month(date); 
       datesPerMonth = findAllDatesForGivenMonth(newLedigeDage, cal.get(Calendar.MONTH)); 
       ledigeDageMap.put(month, datesPerMonth); 
      } 
     } 


    private List<Date> findAllDatesForGivenMonth(List<Date> newLedigeDage, int month) { 
     Calendar cal = Calendar.getInstance(); 
     List<Date> datesForGivenMonth = new ArrayList<>(); 
     for (Date date : newLedigeDage) { 
      if (cal.get(Calendar.MONTH) == month) { 
       datesForGivenMonth.add(date); 
      } 
     } 
     return datesForGivenMonth; 
    } 

Но код не является чистым и не является оптимальным, так как я перебирать те же даты слишком много раз.

Я использую java 1.7 и имею Guava. Я не могу использовать Multimap в этом случае из-за некоторых проблем с архитектурой в моем приложении.

Любые предложения относительно того, как оптимизировать это и сделать его чистым?

+3

Вы хотите проверить код? >> http://codereview.stackexchange.com/ – Tom

+0

Нет, я не хочу просматривать код. Я ищу правильный чистый способ сделать это, и я только что опубликовал то, что я пробовал до сих пор. –

+0

И вы хотите, чтобы кто-то посмотрел на него и предложил лучшие решения. Это одна из целей «Обзор кода». – Tom

ответ

1

Я думаю, что я хотел бы сделать что-то вроде:

public void addLedigeDage(List<Date> newLedigeDage) { 
    for (Date date : newLedigeDage) { 
    Month month = new Month(date); 
    if (!ledigeDageMap.containsKey(month)) { 
     ledigeDageMap.put(month, new ArrayList<>()); 
    } 
    ledigeDageMap.get(month).add(date); 
    } 
} 

Если вы хотите, вы могли бы извлечь:

if (!ledigeDageMap.containsKey(month)) { 
    ledigeDageMap.put(month, new ArrayList<>()); 
} 
ledigeDageMap.get(month).add(date); 

как отдельный метод, называемый нечто вроде addDateToMap быть немного чище.

+0

Я не знаю гуаву, но я подозреваю, что вы могли бы одобрить это выше с помощью магии гуавы. – DaveyDaveDave

2

Существует элегантный Java-8 Решение:

List<Date> dates = Arrays.asList(new Date(10000), new Date(100000)); 
    Map<Month, List<Date>> byMonth = dates.stream() 
      .collect(Collectors.groupingBy(d -> new Month(d))); 
0

Есть несколько проблем с кодом: 1-й: Не врите в коде (месяц содержит месяц и год). Должно быть какое-то более конкретное имя.

2nd: override equals and hashcode method другой мудрый двухмесячный объект с таким же значением месяца и года будет обрабатываться по-разному по карте.

Помимо этого ответа DaveyDaveDave это хорошо.

+0

У месяца уже есть методы equals и hashcode, которые я решил не публиковать в этом вопросе, так как они не дают никакой ценности этому вопросу (то же самое с getters и seters). Также я не программировал сам класс Month, я просто работал с существующим кодом, который я не могу реорганизовать в этой итерации. –

+0

Также неплохо сделать поля вашего hashCode на основе final. – dezhik

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