Преобразование карты с использованием Guava

#java #guava

#java #guava

Вопрос:

У меня есть объект Group, который имеет список элементов, как показано ниже.

 class Group {
    List<E> elements;
    public List<E> getElements() { return elements; }
}
  

У меня есть объект Map, представленный как показано ниже.

 Map<Group, Double> groups = with some values....
  

У меня есть другая карта, как показано ниже.

 Map<Element, Double> elementVal = with some values....
  

Моя окончательная карта должна быть

 Map<Element, Double> = with some values
  

где значение — это умножение значения группы элемента ( groups map) на значение элемента ( elementVal map).

Я ищу преобразование карты, предпочтительно используя Guava или любой другой более чистый способ для этого, а не взрывать карты.

Спасибо.

Комментарии:

1. Какова связь от Group к Element ? Всегда ли карты имеют одинаковый размер? Упорядочены ли ключи?

2. Может Element быть членом более чем одного Group ? Если это так, какую операцию следует использовать для агрегирования?

3. Итак, вы хотели бы умножить каждый element в каждом group.elements из groups на каждый element в elementVal ? И вы предпочитаете Guava.

4. @reto, Группа содержит список элементов. Размер групповой карты и элемента будет другим. например, у меня есть 100 элементов. Затем я сгруппирую эти элементы и создам, скажем, 10 групп.

5. @Boris, Элемент может быть частью только одной группы.

Ответ №1:

Итак…

версия с сокращенными циклами

 @Test 
 public void multiplyMaps() {
 Элемент e1 = новый элемент(1.);
 Элемент e2 = новый элемент(2.);
 Элемент e3 = новый элемент(3.);
 Элемент e4 = новый элемент(4.);

 Map elementVal = новая хэш-карта();
 elementVal.put(e1, e1.d);
 elementVal.put(e2, e2.d);
 elementVal.put(e3, e3.d);
 elementVal.put(e4, e4.d);

 Группа g12 = новая группа (списки.newArrayList(e1, e2));
 Группа g23 = новая группа (списки.newArrayList(e2, e3));
 Группа g34 = новая группа (списки.newArrayList(e3, e4));

 Группы карт = новая хэш-карта(); 
 groups.put(g12, e1.d   e2.d); 
 groups.put(g23, e2.d   e3.d); 
 groups.put(g34, e3.d   e4.d);

 для (окончательной карты.Запись groupEntry : groups.entrySet()) { 
 для (Map.Entry elementValEntry : elementVal.entrySet()) {
 System.out.println(groupEntry.GetValue()   "*"   elementValEntry.GetValue());
 }
 }
 }

Затем мы применяем немного guava для внутреннего цикла;)

@Test 
public void multiplyMaps2() {
 Элемент e1 = новый элемент(1.);
 Элемент e2 = новый элемент(2.);
 Элемент e3 = новый элемент(3.);
 Элемент e4 = новый элемент(4.);

 Map elementVal = новая хэш-карта();
 elementVal.put(e1, e1.d);
 elementVal.put(e2, e2.d);
 elementVal.put(e3, e3.d);
 elementVal.put(e4, e4.d);

 Группа g12 = новая группа (списки.newArrayList(e1, e2));
 Группа g23 = новая группа (списки.newArrayList(e2, e3));
 Группа g34 = новая группа (списки.newArrayList(e3, e4));

 Группы карт = новая хэш-карта(); 
 groups.put(g12, e1.d   e2.d); 
 groups.put(g23, e2.d   e3.d); 
 groups.put(g34, e3.d   e4.d);

 для (окончательной карты.Запись groupEntry : groups.entrySet()) {

 Преобразование коллекции = Collections2.transform(elementVal.entrySet(), новая функция, объект>() {
 @Nullable
 @Переопределить 
 применяется общедоступная строка (@Nullable Map.Entry elementValEntry) {
 возвращает groupEntry.GetValue()   "*"   elementValEntry.GetValue();
 }
 });
 System.out.println(преобразование);
 }
}

И, наконец, преобразование внешнего цикла плюс использование FluentIterable

 @Test 
 public void multiplyMaps3() {
 Элемент e1 = новый элемент(1.);
 Элемент e2 = новый элемент(2.);
 Элемент e3 = новый элемент(3.);
 Элемент e4 = новый элемент(4.);

 конечный элемент карты = новая хэш-карта();
 elementVal.put(e1, e1.d);
 elementVal.put(e2, e2.d);
 elementVal.put(e3, e3.d);
 elementVal.put(e4, e4.d);

 Группа g12 = новая группа (списки.newArrayList(e1, e2));
 Группа g23 = новая группа (списки.newArrayList(e2, e3));
 Группа g34 = новая группа (списки.newArrayList(e3, e4));

 Группы карт = новая хэш-карта(); 
 groups.put(g12, e1.d   e2.d); 
 groups.put(g23, e2.d   e3.d); 
 groups.put(g34, e3.d   e4.d);

 Коллекция> преобразование = Collections2.transform(groups.entrySet(), новая функция, Коллекция>() {
 @Nullable
 @Переопределить 
 применяется общедоступная коллекция (@Nullable final Map.Entry groupEntry) {
 верните Collections2.transform(elementVal.entrySet(), новую функцию, строку>() {
 @Nullable
 @Переопределить 
 применяется общедоступная строка (@Nullable Map.Entry elementValEntry) {
 возвращает groupEntry.GetValue()   "*"   elementValEntry.GetValue();
 }
 });
 }
 });

 Объекты с плавной обработкой = FluentIterable.from(transform).transformAndConcat(новая функция, итерируемая>() {
 @Nullable
 @Переопределить 
 общедоступное повторяемое применение (@Nullable строки коллекции) {
 возвращаемые строки;
 }
 });
 System.out.println(объекты); 
 }

Наконец, у нас есть итерируемый объект, содержащий результаты умножения.

Конечно, это не решение вашей проблемы, потому что вам нужно будет применить еще одно преобразование, которое берет результат из objects и сопоставляет их с Element . Это не так сложно, потому что вам нужно всего лишь изменить строку на какой-то Entry (пару объектов).

Комментарии:

1. Большое спасибо Koziolek за подробное объяснение. Я свяжусь с вами, если столкнусь с какой-либо проблемой.

2. еще одно. В вашем случае, вероятно, вам потребуется переключить внешний и внутренний циклы. Это потому, что вам нужны Element объекты в качестве ключей, и после переключения их будет легче получить