繁体   English   中英

根据地图的String元素创建新分组 <String, List<Object> &gt;

[英]Create new groupings based on the String element of a Map<String, List<Object>>

我有一个名为“ CoordinatesObjects的列表,每个坐标都包含三个值。 两个类型为double x,y和一个String名称。 我的代码接收坐标输入作为输入,并通过创建<String, List<Object>>类型的Map根据名称对它们进行分组。 这样,我将拥有一个与所有相应坐标相关联的名称,而不是将一对坐标与一个名称相关联。

EG:

地图前:

[0.01,0.51] --> A
[0.01,0.56] --> A
[0.01,0.61] --> A
[0.01,0.66] --> AB
[0.01,0.71] --> ABC
[0.01,0.76] --> ABC

其中A,B和C是名称。 如果多个名称同时出现,则表示它们共享相同的坐标。

地图后:

[[0.01,0.01,0.01],[0.51,0.56,0.61]] --> A
[[0.01,0.01], [0.61,0.66]]          --> AB
[[0.01, 0.01], [0.71,0.76]]         --> ABC

我想要实现的是将每个名称与组分开,并将所有坐标链接到该名称。

我要达到的目标的EG:

[[0.01,0.01,0.01,0.01,0.01,0.01],[0.51,0.56,0.61,0.66,0.71,0.76]] --> A
[[0.01,0.01,0.01,0.01], [0.61,0.66,0.71,0.76]]                    --> B
[[0.01,0.01], [0.71,0.76]]                                        --> C

以下是创建Map并按名称分组的代码:

Map<String, List<Coordinates>> newList = coordinateList.stream()
                .collect(Collectors.groupingBy(Coordinates::getName));

有什么办法可以做到这一点? 请注意,名称(例如ABC)没有用逗号或空格分隔,但是如果有可能的解决方案,我已经知道该怎么做(A,B,C)。

座标课:

public class Coordinates {
    private double X;
    private double Y;
    private String name;

    public Coordinates(double dexp, double dent, String name) {
        this.X=dexp;
        this.Y=dent;
        this.name=name;
    }
    @Override
    public String toString() {
        return "["+X+","+Y+"]";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getX() {
        return X;
    }
    public void setX(double x) {
        X = x;
    }
    public double getY() {
        return Y;
    }
    public void setY(double y) {
        Y = y;
    }

}

名称示例:

STEP(One)
STEP(Two)
STEP(One)STEP(Two)

如果我对您的理解正确,我们假设您已经可以轻松到达第二张地图。 这对于任何一个地图都应该起作用,但是您甚至可以基于此稍作优化。 继续这个假设并使用您的Map<String, List<Coordinate>> ,我们可以基于该输入进行累积/合并:

Map<String, List<Coordinate>> myComboMap = /* ... */;
Map<String, List<Coordinate>> myAbsoluteMap = new HashMap<>();
myComboMap.forEach((name, coords) -> {
    List<String> names = /* split up name into list, or just iterate */;
    names.forEach(n -> {
        //merge or create the results for each name
        myAbsoluteMap.compute(n, (key, old) -> {
            if (old == null) {
                //copy list to avoid changing old map
                return new ArrayList<>(coords);
            }
            //or append to an existing list
            old.addAll(coords);
            return old;
        });
    });
});

这也可以通过#flatMap和Collectors#toMap通过流完成,但是该解决方案将涉及创建许多对象,因此为了简单起见,我使用了副作用#forEach。

注意 :这将创建一个单名称映射到它们各自的坐标。 您可以很容易地翻转该地图(两者应该是相当独特的),尽管我自己不确定用例。 请记住,如果两个名称在此地图上具有相同的坐标,则翻转地图可能会导致丢失其中一个名称。 因此,我使用名称->坐标原样保留答案。

将名称拆分任务留给您,并假设您不想使用拆分名称创建新的Coordinate对象,则可以执行以下操作:

   Map<String, List<Coordinates> > newList = coordinateList.stream()
       .flatMap( c -> split( c.getName() ).stream()
                      .map( sn -> new AbstractMap.SimpleEntry<>(sn, c) ) )
       .collect( Collectors.groupingBy(
                 Map.Entry::getKey, 
                 Collectors.mapping(Map.Entry::getValue, Collectors.toList() ) ) );

如何创建列表<object>带有字段字符串和 Map <string, set<string> &gt; 从另一个列表<object2><div id="text_translate"><p> Class Object2具有标准的 getter 并具有String字段folder 、 file和version 。 它被命名为SourceInfo</p><p> List&lt;SourceInfo&gt; source包含上面提到的三个字段。</p><p> 我的目标是从List&lt;SourceInfo&gt;创建一个List&lt;Info&gt; &gt; 。</p><p> 新List的 class 为Info ,如下图所示。</p><pre> public class Info { private final String folder; private final Map&lt;String, Set&lt;String&gt;&gt; file; public static Builder builder() { return new Builder(); } public static Builder builder(Info info) { return new Builder(info); } private Info(Builder builder) { this.folder = builder.folder; this.file = builder.file; } public String getFolder() { return folder; } public Map&lt;String, Set&lt;String&gt;&gt; getFile() { return file; } // autogenerated toString, hashCode, and equals public static class Builder { private String folder; private Map&lt;String, Set&lt;String&gt;&gt; file; private Builder() {} private Builder(Info info) { this.folder = info.folder; this.file = info.file; } public Builder with(Consumer&lt;Builder&gt; consumer) { consumer.accept(this); return this; } public Builder withFolder(String folder) { this.folder = folder; return this; } public Builder withFile(Map&lt;String, Set&lt;String&gt;&gt; file) { this.file = file; return this; } public Info build() { return new Info(this); } }</pre><p> 到目前为止,我尝试的是在构建器模式中创建一个集合。</p><pre> List&lt;SourceInfo&gt; source; // error: gc overhead limit exceeded List&lt;Info&gt; infoList = source.stream().map(e -&gt; Info.builder().withFolder(e.getFolder()).withFile(source.stream().collect(Collectors.groupingBy(SourceInfo::getKey, Collectors.mapping(SourceInfo::getVersion, Collectors.toSet())))).build()).collect(Collectors.toList()); Map&lt;String, Set&lt;String&gt;&gt; map = source.stream().collect(Collectors.groupingBy(SourceInfo::getKey, Collectors.mapping(SourceInfo::getVersion, Collectors.toSet()))); List&lt;Info&gt; info = source.stream().map(e -&gt; Info.builder().withFolder(e.getFolder()).withFile(map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))).build()).collect(Collectors.toList());</pre><p> 所需的 output。 以下语法可能已关闭。</p><pre> // [String, Map&lt;String, Set&lt;String&gt;&gt;] Info [folder, [key=file [value=version]]]...</pre><p> 我是 Java 的新手,不胜感激。</p><p> 我想了解如何使用 java8 和 for 循环来做到这一点。</p><p> 谢谢你。</p></div></object2></string,></object>

[英]How to create a List<Object> with fields String and Map<String, Set<String>> from another List<Object2>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 排序列表<map<string,object> > 基于价值</map<string,object> 创建一个新地图 <String, List<String> &gt;具有其他地图中的选择性元素 <String, List<String> &gt; 如何基于字符串创建一种新型的对象? 过滤并收集地图<String, List<Object> &gt; 到地图<String, List<Object> &gt; 基于条件 如何创建列表<object>带有字段字符串和 Map <string, set<string> &gt; 从另一个列表<object2><div id="text_translate"><p> Class Object2具有标准的 getter 并具有String字段folder 、 file和version 。 它被命名为SourceInfo</p><p> List&lt;SourceInfo&gt; source包含上面提到的三个字段。</p><p> 我的目标是从List&lt;SourceInfo&gt;创建一个List&lt;Info&gt; &gt; 。</p><p> 新List的 class 为Info ,如下图所示。</p><pre> public class Info { private final String folder; private final Map&lt;String, Set&lt;String&gt;&gt; file; public static Builder builder() { return new Builder(); } public static Builder builder(Info info) { return new Builder(info); } private Info(Builder builder) { this.folder = builder.folder; this.file = builder.file; } public String getFolder() { return folder; } public Map&lt;String, Set&lt;String&gt;&gt; getFile() { return file; } // autogenerated toString, hashCode, and equals public static class Builder { private String folder; private Map&lt;String, Set&lt;String&gt;&gt; file; private Builder() {} private Builder(Info info) { this.folder = info.folder; this.file = info.file; } public Builder with(Consumer&lt;Builder&gt; consumer) { consumer.accept(this); return this; } public Builder withFolder(String folder) { this.folder = folder; return this; } public Builder withFile(Map&lt;String, Set&lt;String&gt;&gt; file) { this.file = file; return this; } public Info build() { return new Info(this); } }</pre><p> 到目前为止,我尝试的是在构建器模式中创建一个集合。</p><pre> List&lt;SourceInfo&gt; source; // error: gc overhead limit exceeded List&lt;Info&gt; infoList = source.stream().map(e -&gt; Info.builder().withFolder(e.getFolder()).withFile(source.stream().collect(Collectors.groupingBy(SourceInfo::getKey, Collectors.mapping(SourceInfo::getVersion, Collectors.toSet())))).build()).collect(Collectors.toList()); Map&lt;String, Set&lt;String&gt;&gt; map = source.stream().collect(Collectors.groupingBy(SourceInfo::getKey, Collectors.mapping(SourceInfo::getVersion, Collectors.toSet()))); List&lt;Info&gt; info = source.stream().map(e -&gt; Info.builder().withFolder(e.getFolder()).withFile(map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))).build()).collect(Collectors.toList());</pre><p> 所需的 output。 以下语法可能已关闭。</p><pre> // [String, Map&lt;String, Set&lt;String&gt;&gt;] Info [folder, [key=file [value=version]]]...</pre><p> 我是 Java 的新手,不胜感激。</p><p> 我想了解如何使用 java8 和 for 循环来做到这一点。</p><p> 谢谢你。</p></div></object2></string,></object> Java:对列表进行排序<Map<String, Object> &gt; dataList = 新的 ArrayList <Map<String, Object> &gt;(dataMap.values()) 使用新的 object 类型从拆分字符串创建嵌套的 map 转换清单 <Map<String, Object> &gt;列出 <String> 名单 <Map<String,String> &gt; vs列表 <Object> 比较列表<map<string, string> &gt; 到列表<map<string, object> &gt; Java </map<string,></map<string,>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM