2017-02-23 47 views
-2

我负责以下问题:给定一组IngredientPortion(我制作的一个对象),如果IngredientPortions中的两个元素是相同的成分(Ingredient是另一个对象,它是IngredientPortion对象的一个​​组件),我是应该结合IngredientPortion元素。例如,如果我给出的IngredientPortion数组有两个元素,比如1.5盎司的avacodo部分和2.0 oz的另一个鳄梨部分,我应该生成一个新的IngredientPortion数组,其中包含1个元素的鳄梨: 3.5盎司。如何将具有相同关键字的值合并到一个哈希映射中的一个值中?

我不知道如何做到这一点,但我正在考虑使用Strings的hashmap作为键,代表成分名称和IngredientPortion对象的值。如果hashmap已经有了给定的ingredientPortion.getName()的关键字,那么我会为该关键字添加特定的成分比例,但我不确定如何组合成分数量。它会自动结合它还是将它作为两个不同的成分比例存储在这一个键下?提前致谢!

+0

'map.put(duplicatePortion。getName(),新的IngredientPortion(duplicatePortion.getName(),alreadyStoredPortion.quantity + duplicatePortion.quantity)' –

+0

[HashMap在同一个键下具有多个值的HashMap的可能重复](http://stackoverflow.com/questions/4956844/hashmap -with-multiple-values-under-the-same-key) – nhouser9

+0

您尚未提供您现有的代码或显示地图的定义,特别是输入值的类型。它是'Double','BigDecimal'还是自定义类? –

回答

0

我使用Java 8流和groupingBy方法为您的问题实施了两种解决方案。我希望这能帮到您。

import java.util.*; 
import java.util.stream.Collectors; 

public class Main { 
    public static class Ingredient { 
     private final String name; 
     private final int quantity; 

     public Ingredient(String name, int quantity) { 
      Objects.requireNonNull(name); 
      this.name = name; 
      this.quantity = quantity; 
     } 

     public String getName() { 
      return name; 
     } 

     public int getQuantity() { 
      return quantity; 
     } 

     @Override 
     public String toString() { 
      return "Ingredient{" + 
        "name='" + name + '\'' + 
        ", quantity=" + quantity + 
        '}'; 
     } 
    } 

    public static void main(String[] args) { 
     Ingredient[] ingredients = new Ingredient[]{ 
      new Ingredient("banana", 1), 
      new Ingredient("cherry", 5), 
      new Ingredient("banana", 3), 
      new Ingredient("floor", 1) 
     }; 

     // First solution: Group all quantities 
     Map<String, List<Integer>> collect = Arrays.stream(ingredients) 
       .collect(Collectors.groupingBy(Ingredient::getName, 
         Collectors.mapping(Ingredient::getQuantity, Collectors.toList()) 
       )); 
     System.out.println(collect); 

     // Second solution: Sum all quantities 
     Map<String, Integer> sum = Arrays.stream(ingredients) 
       .collect(
        Collectors.groupingBy(Ingredient::getName, 
        Collectors.summingInt(Ingredient::getQuantity) 
       )); 
     System.out.println(sum); 
    } 
} 
+0

非常感谢你!我很感激 – etnie1031

+0

如果我回答你的问题,请upvote我的帖子,并单击答案图标;)。 –

1

如果你的hashmap存储值,那么你可以用它来填充一个值。此作品无论是第一成分(即它不是在地图)或它的第二个(这需要在地图上已经加入到价值:

map.put(ingredientKey, map.getOrDefault(ingredientKey, 0.0) + ingredientAmount); 
+0

仅适用于'Map '(或其他数字类型)。部分可能是数量和计量单位的另一个对象。 –

+0

@JimGarrison你是对的!幸运的是我设法得到了我想要的其他一些stackoverflow用户的帮助。 – etnie1031

0

我不知道该怎么办这一点,但我想用字符串作为键的一个HashMap,占成份名称,并IngredientPortion对象的值。

听起来不错迄今。

如果HashMap中已经有一个关键的给定的ingredientPortion.getName(),我会把那个特定的成分分配给那个关键,但我不知道如何结合成分的数量。它会自动结合它还是将它作为两个不同的成分比例存储在这一个键下?

显然,处理IngredientPortion时没有问题,其名称尚未注册为映射中的键。但是,如果密钥已经注册,则使用该密钥将新值添加到地图中将简单替换分配给该密钥的先前值,而不是以某种方式组合这些值。 The documentation for the Map interface应该清楚这一点。

事实上,你甚至希望Map会自动合并值,当如何这样做,甚至是否可能这样做取决于值的类型?听起来像可能不确定如何形成这样的组合。如果是这样,那么确定这一点就成为你的首要任务。这也是一个特定类型的问题,所以我们无法向您提供有关细节的建议。

一旦你知道如何以合适的方式组合这些对象,使用。例如,查看地图中的每个名称,并根据是否找到它,插入或替换其值。

+0

非常感谢!我现在填充了地图,但是如何将地图的值转换回一个包含ingredientPortion对象的数组?我尝试使用newArray = ingredientMap.values()。toArray(),但它给了我一个错误消息,说不能从Object []转换成IngredientPortion [] – etnie1031

+0

@ etnie1031,使用'Collection.toArray()'的版本, (适当类型)数组作为它的参数。例如,'ingredientMap.values()。toArray(new IngredientPortion [ingredientMap.size()])'。 –

相关问题