将唯一值插入哈希映射

时间:2021-01-02 22:35:27

标签: java hashmap grouping

我正在尝试将某个类的列表插入到哈希映射中。键应该是列表中的字段之一,在我的例子中是 id,哈希映射的值应该是列表项,以键作为其 ID。

这是我尝试做的一个例子:

// example class

public class Dog{
  int id,
  int name,
  int foodEaten
}

// getters

// dog objects
Dog dog1 = new Dog(1,"Dog1", "Cheese")
Dog dog2 = new Dog(1,"Dog1", "Meat")

Dog dog3 = new Dog(2,"Dog2", "Fish")
Dog dog4 = new Dog(2,"Dog2", "Milk")

List<Dog> dogList = new ArrayList<>();

//insert dog objects into dog list

//Creating HashMap that will have id as the key and dog objects as the values
HashMap<Integer, List<Dog>> map = new HashMap<>(); 

这就是我想要做的

for (int i = 0; i < dogList.size()-1; i++) {
  List<Dog> cx = new ArrayList<>();
  if (dog.get(i).getId() == dog.get(i+1).getId()){
    cx.add(dog.get(i));
  }
   map.put(dog.get(i).getId(), cx);
}

但是,我得到了这个结果:

{
  "1": [
    {
      "id": 1,
      "name": "Dog1",
      "foodEaten": "Cheese"
    }
  ],
  "2": []
}

但这就是我想要实现的:

{
  "1": [
    {
      "id": 1,
      "name": "Dog1",
      "foodEaten": "Cheese"
    },
    {
      "id": 1,
      "name": "Dog1",
      "foodEaten": "Meat"
    }
  ],
  "2": [
    {
      "id": 2,
      "name": "Dog2",
      "foodEaten": "Fish"
    },
    {
      "id": 2,
      "name": "Dog2",
      "foodEaten": "Milk"
    }
  ]
}

3 个答案:

答案 0 :(得分:2)

您可以使用 Collectors.groupingBy(Dog::getId) 将具有相同 id 的狗分组。

演示:

public class Main {
    public static void main(String[] args) {
        List<Dog> list = List.of(new Dog(1, "Dog1", "Cheese"), new Dog(1, "Dog1", "Meat"), new Dog(2, "Dog2", "Fish"),
                new Dog(2, "Dog2", "Milk"));

        Map<Integer, List<Dog>> map = list.stream().collect(Collectors.groupingBy(Dog::getId));

        System.out.println(map);
    }
}

输出:

{1=[Dog [id=1, name=Dog1, foodEaten=Cheese], Dog [id=1, name=Dog1, foodEaten=Meat]], 2=[Dog [id=2, name=Dog2, foodEaten=Fish], Dog [id=2, name=Dog2, foodEaten=Milk]]}

toString 实现:

public String toString() {
    return "Dog [id=" + id + ", name=" + name + ", foodEaten=" + foodEaten + "]";
}

答案 1 :(得分:1)

Dog dog1 = new Dog(1, "Dog1", "Cheese");
Dog dog2 = new Dog(1, "Dog1", "Meat");

Dog dog3 = new Dog(2, "Dog2", "Fish");
Dog dog4 = new Dog(2, "Dog2", "Milk");

List<Dog> dogList = List.of(dog1, dog2, dog3, dog4);
//insert dog objects into dog list
        
//Creating HashMap that will have id as the key and dog objects as the values
Map<Integer, List<Dog>> map = new HashMap<>();

for (Dog dog : dogList) {
    map.computeIfAbsent(dog.id, k -> new ArrayList<>())
            .add(dog);
}

map.entrySet().forEach(System.out::println);

印刷品

1=[{1, Dog1, Cheese, {1, Dog1, Meat]
2=[{2, Dog2, Fish, {2, Dog2, Milk]

狗类

static class Dog {
    
    int id;
    String name;
    String foodEaten;
    
    public Dog(int id, String name, String foodEaten) {
        this.id = id;
        this.name = name;
        this.foodEaten = foodEaten;
    }
    
    public String toString() {
        return String.format("{%s, %s, %s", id, name, foodEaten);
    }
    
}

答案 2 :(得分:1)

嗨,Tosh,欢迎来到 Stackoverflow。

问题出在检查两个对象的 ID 时的 if 语句中。

for (Dog dog : dogList) {
  if(dog.getId() == dog.getId()){
     crMap.put(cr.getIndividualId(), clientReceivables.);
  }
}

在这里,您检查名为“dog”的同一对象的 ID,并且在此 if 语句中您将始终得到 True。这就是为什么它会用两个 ID 的所有值填充您的地图。

您遇到的另一个问题是您的 dog4 的 ID 等于 1,即 dog1 和 dog2 的 ID。考虑到这一点,您仍然无法实现您想要的目标,因此也请检查一下。

现在是解决方案。如果您想浏览列表并将每只狗与下一只进行比较,那么您需要写出不同的内容。我不确定您是只使用 java 还是使用 android,但是有一个解决方案可以解决这个问题,并且您的代码更简洁。

使用 Java 8,您可以获得 Stream API,它可以帮助您解决这个问题。检查它here

对于 android,你也有 android-linq,你可以检查 here