【问题标题】:Merge Lists or Append Fields in List with unique values在具有唯一值的列表中合并列表或附加字段
【发布时间】:2021-04-19 04:51:18
【问题描述】:
List A = [
           MyClass(country=BE, userNumber=[12345], cityName = Brussels ),
                  (country= BE , userNumber=[12345], cityName = Bruges ),
                  (country= DE , userNumber=[54645], cityName = Frankfurt )
         ]


List B = [
          MyClass(country=BE, userNumber=[34356], cityName = Brussels ),
                 (country= BE , userNumber=[64325], cityName = Namur )
         ]

我必须以这样的方式合并这两个列表,最终结果会像

   Expected Final List = [
                        MyClass(country=BE, userNumber=[12345,34356], cityName = Brussels ),
                             (country= BE , userNumber=[12345], cityName = Bruges ),
                             (country= DE , userNumber=[54645], cityName = Frankfurt ),
                             (country= BE , userNumber=[64325], cityName = Namur )
            ]

尝试过的解决方案:

  • 获取两个列表的城市名称,如果为 true,则列表 A 是否包含列表 B,然后在列表 B 上运行 for 循环并找到相同的城市名称并尝试将用户编号附加到列表 A。

上述解决方案工作了一半,不确定它的效率如何。请帮忙。

【问题讨论】:

  • 是否有机会发布一些代码来显示您如何获得List AList B
  • List A 来自 DB,List B 是新创建的,将新的 userNumber 添加到 List A 和 DB 中。
  • 覆盖 POJO 的 equals 方法,然后使用 ArrayList 的 contains 方法

标签: java arraylist java-8 java-stream array-merge


【解决方案1】:

您需要使用字段 countrycityName 覆盖 POJO 类中的 equals()hashcode() 方法。 那么

  1. 将所有元素添加到名为finalList 的列表中。

  2. 迭代finalList 中的每个元素并将新元素添加到map 中。

  3. 如果在地图中发现重复元素,则将地图中对象的userNumber 与重复对象合并。并添加回地图。

  4. 重复第 2 步和第 3 步,直到迭代完成。

  5. map's 密钥转换为finalList

例子:

import java.util.*;
import java.util.stream.IntStream;

class MyClass{
    private String country;
    private int[] userNumber;
    private String cityName ;
    MyClass(String country,int[] userNumber,String cityName){
        this.country = country;
        this.userNumber = userNumber;
        this.cityName = cityName;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public int[] getUserNumber() {
        return userNumber;
    }

    public void setUserNumber(int[] userNumber) {
        this.userNumber = userNumber;
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyClass myClass = (MyClass) o;
        return country.equals(myClass.country) &&
                cityName.equals(myClass.cityName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(country, cityName);
    }
}

public class Test {

    public static void main(String args[]){
        List<MyClass> listA = new ArrayList();
        List<MyClass> finalList =new ArrayList();
                listA.add(new MyClass("BE", new int[]{12345},"Brussels"));
        listA.add(new MyClass("BE",new int[]{12345},"Bruges"));
        listA.add(new MyClass("DE",new int[]{54645},"Frankfurt"));
        List<MyClass> listB = new ArrayList();
        listB.add(new MyClass("BE",new int[]{34356},"Brussels"));
        listB.add(new MyClass("BE",new int[]{64325},"Namur"));
        finalList.addAll(listA);
        finalList.addAll(listB);
        HashMap<MyClass,MyClass> map = new HashMap<>();
        for(MyClass myClass : finalList){
            MyClass objInMap = map.get(myClass);
            if(objInMap!=null){
                int[] userNum = IntStream.concat(Arrays.stream(objInMap.getUserNumber()),
                        Arrays.stream(myClass.getUserNumber()))
                        .distinct()
                        .toArray();
               objInMap.setUserNumber(userNum);
            }else{
                map.put(myClass,myClass);
            }
        }
        finalList = new ArrayList<>(map.keySet());
        System.out.println(finalList);
    }
}

【讨论】:

    【解决方案2】:
        List<Address> first = new ArrayList<>();
        List<Address> second = new ArrayList<>();
        for (Address address : first) {
            int index = second.indexOf(address);
            if(index >= 0){
               first.getUserNumber().addAll(second.get(index).getUserNumber())
            }
        }
    

    不要忘记重写equals方法并忽略equals方法中的userNumber字段。

    【讨论】:

      【解决方案3】:
          public static <T> T[] concatAll(T[] first, T[]... rest) {
              int totalLength = first.length;
              for (T[] array : rest) {
                  totalLength += array.length;
              }
              T[] result = Arrays.copyOf(first, totalLength);
              int offset = first.length;
              for (T[] array : rest) {
                  System.arraycopy(array, 0, result, offset, array.length);
                  offset += array.length;
              }
              return result;
          }
      
          public static void main(String[] args) {
              List<MyClass> listA = new ArrayList();
              List<MyClass> finalList = new ArrayList();
              listA.add(new MyClass("BE", new Integer[]{12345}, "Brussels"));
              listA.add(new MyClass("BE", new Integer[]{12345}, "Bruges"));
              listA.add(new MyClass("DE", new Integer[]{54645}, "Frankfurt"));
              List<MyClass> listB = new ArrayList();
              listB.add(new MyClass("BE", new Integer[]{34356}, "Brussels"));
              listB.add(new MyClass("BE", new Integer[]{64325}, "Namur"));
              finalList.addAll(listA);
              finalList.addAll(listB);
              List<MyClass> merged = new ArrayList<>();
              finalList.parallelStream().collect(Collectors.groupingBy(cl -> (cl.getCountry() + cl.getCityName()), Collectors.toList()))
                      .forEach((name, item) -> {
                          item.stream().reduce((a, b) -> new MyClass(a.getCountry(), concatAll(a.getUserNumber(), b.getUserNumber()), a.getCityName())).ifPresent(merged::add);
      
                      });
              System.out.println(merged);
          }
      }
      
      class MyClass {
          private String country;
          private Integer[] userNumber;
          private String cityName;
      
          MyClass(String country, Integer[] userNumber, String cityName) {
              this.country = country;
              this.userNumber = userNumber;
              this.cityName = cityName;
          }
      
          public String getCountry() {
              return country;
          }
      
          public void setCountry(String country) {
              this.country = country;
          }
      
          public Integer[] getUserNumber() {
              return userNumber;
          }
      
          public void setUserNumber(Integer[] userNumber) {
              this.userNumber = userNumber;
          }
      
          public String getCityName() {
              return cityName;
          }
      
          public void setCityName(String cityName) {
              this.cityName = cityName;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              MyClass myClass = (MyClass) o;
              return country.equals(myClass.country) &&
                      cityName.equals(myClass.cityName);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(country, cityName);
          }
      Maybe, It is a great way.
      

      【讨论】:

        猜你喜欢
        • 2012-01-15
        • 1970-01-01
        • 2021-03-18
        • 2012-08-25
        • 1970-01-01
        • 1970-01-01
        • 2020-03-04
        • 2010-11-25
        • 1970-01-01
        相关资源
        最近更新 更多