首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建类似于笛卡儿乘积的三种不同类型列表的数据结构?

如何创建类似于笛卡儿乘积的三种不同类型列表的数据结构?
EN

Stack Overflow用户
提问于 2020-08-13 15:18:27
回答 1查看 282关注 0票数 0

我想要创建一个DataStructure,它将类似于三个列表的笛卡尔积。我还参考了尤尔根的现有答案,建议使用flatMap。我也试过了。但我的条件是filterValue列表在types列表中。所以flatMap不会在这里工作。因为filterValues可以是0 or more。因此,根据这个笛卡儿乘积(我们可以称之为组合)将发生变化。

对于每个列表,measures, types & filterValues的大小可能不同。如果measure列表为空。然后,组合将仅为types & filterValues ( measure将设置为null )。我在if-else块的注释中添加了这些不同的场景

我有以下几种类型的清单:

  1. List<String> measures
  2. List<Type> types
  3. List<FilterValue> filterValues

例如,输入结构是:

代码语言:javascript
复制
{
  "measures": [
    "m1",
    "m2",
    "m3"
  ],
  "types": [
    {
      "type": "type-1",
      //some more fields
      "filterValues": [
        //no filter values present
      ]
    },
    {
      "type": "type-2",
      //some more fields
      "filterValues": [
        {
          "filterValue": "t2f1"
          //some more fields
        },
        {
          "filterValue": "t2f2"
          //some more fields
        }
      ]
    }
  ]
}

在上述情况下,我期望的输出数据结构是

代码语言:javascript
复制
m1  type-1 null
m1  type-2 t2f1 
m1  type-2 t2f2 

m2  type-1 null
m2  type-2 t2f1 
m2  type-2 t2f2 

m3  type-1 null
m3  type-2 t2f1 
m3  type-2 t2f2 

然后,将上述值设置为以下类:

代码语言:javascript
复制
class SearchArea {
    String measure;
    String type;
    TypeCombi typeFileter;
    //constructor for measure & type
    //constructor for all three
    //getters & setters
}

class TypeCombi {
    String type;
    String name; //it is mapped with filterValue
    //constructor for above two fields
    //getters & setters
}

Type & FilterValue如下所示

代码语言:javascript
复制
class Type {
    String type;
    List<FilterValue> filterValues;
    //some more fields
    //getters and setters
}

class FilterValue {
    String filterValue;
    //some more fields
    //getters and setters
}

我能够使用下面的getSearchAreas函数实现预期的输出。但在本例中,我使用了多个(两个) for循环。这个代码块可以使用stream/flatmap而不是两个for loops清理吗?还有更好的方法来处理多个if/ each块吗?(我在每个if/else块的前面为它的场景添加了注释)

代码语言:javascript
复制
private List<SearchArea> getSearchAreas(List<String> measures, List<Type> types){
    List<SearchArea> searchAreas = new ArrayList<>();

    //measures & types both are empty
    if ((measures == null || measures.isEmpty())
            && (types == null || types.isEmpty()))
        return Collections.emptyList();

    //one or more measure and zero types
    else if (measures != null && !measures.isEmpty()
            && (types == null || types.isEmpty())) {
        searchAreas = measures
                .stream()
                .map(measure -> new SearchArea(measure, null))
                .collect(Collectors.toList());
        return searchAreas;
    }
    //zero measures and one or more types
    else if ((measures == null || measures.isEmpty())) {
        for (type type : types) {
            if (type.getFilterValues() == null
                    || type.getFilterValues().isEmpty()) {
                searchAreas.add(new SearchArea(null, type.getType()));
            } else {
                searchAreas.addAll(type.getFilterValues()
                        .stream()
                        .map(filterValue -> new SearchArea(null,
                                type.getType(),
                                new TypeCombi(type.getType(),
                                        filterValue.getFilterValue())))
                        .collect(Collectors.toList()));
            }
        }
        return searchAreas;
    }
    //one or more measures and one or more types
    else {
        for (String measure : measures) {
            for (Type type : types) {
                if (type.getFilterValues() == null
                        || type.getFilterValues().isEmpty()) {
                    searchAreas.add(new SearchArea(measure, type.getType()));
                } else {
                    searchAreas.addAll(type.getFilterValues()
                            .stream()
                            .map(filterValue -> new SearchArea(measure,
                                    type.getType(),
                                    new TypeCombi(type.getType(),
                                            filterValue.getFilterValue())))
                            .collect(Collectors.toList()));
                }
            }
        }
        return searchAreas;
    }
}

如果有人能帮助我以更清洁的方式重组上面的结构,那就太好了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-13 15:55:14

我想这就是你想要的。请注意,有时不使用流更干净。

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
    List<String> strings = Collections.emptyList();
    List<Integer> ints = Arrays.asList(1, 2, 3);

    if (strings == null || strings.isEmpty()) {
        strings = Collections.singletonList(null);
    }

    if (ints == null || ints.isEmpty()) {
        ints = Collections.singletonList(null);
    }

    for (String str : strings) {
        for (Integer integer : ints) {
            // In your code doubles comes from a property of integer.
            List<Double> doubles = integer == null ? Collections.emptyList() : Arrays.asList(1.0d, 2.0d, 3.0d);

            if (doubles == null || doubles.isEmpty()) {
                doubles = Collections.singletonList(null);
            }

            for (Double doubler : doubles) {
                // Create your object here.
                System.out.format(Locale.US, "    str = %s, int = %d, double = %f %n", str, integer, doubler);
            }
        }
    }
}

产出如下:

代码语言:javascript
复制
str = null, int = 1, double = 1.000000 
str = null, int = 1, double = 2.000000
str = null, int = 1, double = 3.000000
str = null, int = 2, double = 1.000000
str = null, int = 2, double = 2.000000 
str = null, int = 2, double = 3.000000
str = null, int = 3, double = 1.000000
str = null, int = 3, double = 2.000000
str = null, int = 3, double = 3.000000
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63398192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档