java 基于对象字段的单独数组列表

64jmpszr  于 2023-02-02  发布在  Java
关注(0)|答案(4)|浏览(107)

我有一个类Obj,如下所示:

public class Obj{
    private String size
    private String shape
    private String name
}

在我的另一个类中,我有一个Map<String,List<Obj>>
对于我的Map中的每个String,我想基于我的MapString,重新组合我的List中的每个Obj,其中shape和/或size相等。
现在我有这样的想法:

functionName(Map<String, List<Obj>> objMap){
    objMap.foreach((type,objs) -> {
        switch(type){
            case "type_1":
                // regroup objs by shape
                // then do some treatment
            case "type_2":
                // regroup objs by size
                // then do some treatment
            case "type_3":
                // regroup objs by shape & size
                // then do some treatment
        }
    }
}

从这里开始我有点纠结于如何从我的List<Obj>中得到一个List<List<Obj>>。任何想法都会帮助我,即使不是很优化。

数值和预期结果:

例如,我有一个Map为:

{
  "key" :"type_1",
  "value" : [
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_1"
    },
    {
      "size" : "m2",
      "shape" : "s1",
      "name":"Obj_2"
    },
    {
      "size" : "m3",
      "shape" : "s2",
      "name":"Obj_3"
    }
  ]
}

然后在我的函数中我应该在case "type_1"中,所以我会按形状对它们进行分组,返回如下内容:

[
  [
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_1"
    },
    {
      "size" : "m2",
      "shape" : "s1",
      "name":"Obj_2"
    }
  ],
  [
    {
      "size" : "m3",
      "shape" : "s2",
      "name":"Obj_3"
    }
    
  ]
]

但是如果我的keytype_3,我应该:

[
  [
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_1"
    }
  ],
  [
    {
      "size" : "m2",
      "shape" : "s1",
      "name":"Obj_2"
    }
  ],
  [
    {
      "size" : "m3",
      "shape" : "s2",
      "name":"Obj_3"
    }
  ]
]

因为它们都没有相同的shapesize
如果我的Map是:

{
  "key" :"type_3",
  "value" : [
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_1"
    },
    {
      "size" : "m2",
      "shape" : "s1",
      "name":"Obj_2"
    },
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_3"
    }
  ]
}

那么我应该得到:

[
  [
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_1"
    },
    {
      "size" : "m1",
      "shape" : "s1",
      "name":"Obj_3"
    }
  ],
  [
    {
      "size" : "m2",
      "shape" : "s1",
      "name":"Obj_2"
    }
  ]
]
ni65a41a

ni65a41a1#

形状的例子(但你得到的想法):

List<List<Obj>> regroup(List<Obj> objs) {
    return new ArrayList<>(
       objs.stream()
         .collect(Collectors.groupingBy(Obj::getShape))
         .values()
    );
 }
anauzrmj

anauzrmj2#

定义一个List<List<Obj>> finalList,在finalList中保留一个map跟踪某个类型的列表的索引。
Map<String, Integer> indexMap;
每当你得到一个类型为1的对象时,试着像这样得到list
List<Obj> l1 = indexMap.getOrElse(new ArrayList());
然后将对象追加到该列表中,并放回最终列表的索引中。

List<List<Obj>> finalList = new ArrayList<>();
        Map<String, Integer> indexMap = new HashMap<>();
        
        functionName(Map<String, List<Obj>> objMap){
            objMap.foreach((type,objs) -> {
                switch(type){
                    case "type_1":
                        Integer index = indexMap.getOrDefault(type_1, -1);
                        List<Obj> list = index != -1 ? finalList.get(index) : new ArrayList<Obj>();
                        list.add(obj);
                        finalList.add(index, list); // do this for other types
                        // regroup objs by shape
                        // then do some treatment
                    case "type_2":
                        // regroup objs by size
                        // then do some treatment
                    case "type_3":
                        // regroup objs by shape & size
                        // then do some treatment
                }
            }
        }
umuewwlo

umuewwlo3#

您应该尝试创建嵌套的Map<String, Map<String, List<Obj>>>来存储分组后的值。
例如:

Map<String, Map<String, List<Obj>>> results = new HashMap<>();

不过,我会为分组记录创建另一个类,以使代码更具可读性:

class GroupedObj{
   Map<String, List<Obj>> records = new HashMap<>(); 
}

Map<String, GroupedObj> results = new HashMap<>();
nnt7mjpx

nnt7mjpx4#

您应该能够使用groupingBy收集器:

Map<String, List<Obj>> yourMap = ...;
List<List<Obj>> byShape = new ArrayList<>(yourMap.values().stream()
  .flatMap(Collection::stream)
  .collect(Collectors.groupingBy(Obj::getShape))
  .values());

作为一种方法:

static <T> List<List<Obj>> partition(
    final Map<String, List<Obj>> map,
    final Function<? super Obj, ? extends T> key) {
  return new ArrayList<>(map.values().stream() // Stream<List<Obj>>
      .flatMap(Collection::stream) // Stream<Obj>
      .collect(Collectors.groupingBy(key)) // Map<T, List<Obj>>
      .values() // Collection<List<Obj>>
  ); // List<List<Obj>>
}

调用方法:

final Map<String, List<Obj>> yourMap = ...;
final List<List<Obj>> shapes = partition(yourMap, Obj::getShape);

如果你只提取了列表,不需要处理Map-在这种情况下,"Map"部分与问题无关,应该/可以被删除-方法看起来几乎相同(经典的"留给读者作为练习",但在这里):

static <T> List<List<Obj>> partition(
    final List<Obj> list,
    final Function<? super Obj, ? extends T> key) {
  return new ArrayList<>(list.stream() // Stream<Obj>
      .collect(Collectors.groupingBy(key)) // Map<T, List<Obj>>
      .values() // Collection<List<Obj>>
  ); // List<List<Obj>>
}

用法:

final List<Obj> yourList = ...;
final List<List<Obj>> shapes = partition(yourList, Obj::getShape);

相关问题