Java ArrayList of HashMaps返回到Spring端点

huangapple go评论79阅读模式
英文:

Java ArrayList of hasMap to return in Spring endpoint

问题

import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class MyClass {
    
    String text = "hi";
    String language = "pt-br";
    String item = "1";
    
    public static void main(String args[]) {
        
        MyClass myObj1 = new MyClass();
        myObj1.text = "ola";
        myObj1.language = "pt-br";
        myObj1.item = "1";
 
        MyClass myObj2 = new MyClass();
        myObj2.text = "hi";
        myObj2.language = "en";
        myObj2.item = "1";

        MyClass myObj3 = new MyClass();
        myObj3.text = "holaa";
        myObj3.language = "es";
        myObj3.item = "2";
        
        MyClass myObj4 = new MyClass();
        myObj4.text = "olaaaaa";
        myObj4.language = "pt-br";
        myObj4.item = "2";

        MyClass myObj5 = new MyClass();
        myObj5.text = "helllooo";
        myObj5.language = "eng";
        myObj5.item = "3";

        List<MyClass> lang = new ArrayList<MyClass>();
        lang.add(myObj1);
        lang.add(myObj2);
        lang.add(myObj3);
        lang.add(myObj3);
        lang.add(myObj4);
        
        ArrayList<HashMap<String, List<HashMap<String, String>>>> lista = new ArrayList<>();

        HashMap<String, List<HashMap<String, String>>> itemMap = new HashMap<>();
        String currentItem = "";

        for (int i = 0; i < lang.size(); i++) {
            MyClass currentLang = lang.get(i);
            if (!currentItem.equals(currentLang.item)) {
                if (!currentItem.isEmpty()) {
                    lista.add(itemMap);
                    itemMap = new HashMap<>();
                }
                currentItem = currentLang.item;
            }

            HashMap<String, String> langMap = new HashMap<>();
            langMap.put(currentLang.language, currentLang.text);

            List<HashMap<String, String>> langList = new ArrayList<>();
            langList.add(langMap);

            itemMap.put("item_id", currentItem);
            itemMap.put("language", langList);

            if (i == lang.size() - 1) {
                lista.add(itemMap);
            }
        }

        System.out.println(lista.toString());
    }
}
英文:

I have some sample objects that will be included in an ArrayList, and these items must appear in the specific format, the problem that each item must be is a new position of an array in the json return.

follow the code I have developed so far:

import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class MyClass {
String text = &quot;hi&quot;;
String language = &quot;pt-br&quot;;
String item = &quot;1&quot;;
public static void main(String args[]) {
MyClass myObj1 = new MyClass();
myObj1.text = &quot;ola&quot;;
myObj1.language = &quot;pt-br&quot;;
myObj1.item = &quot;1&quot;;
MyClass myObj2 = new MyClass();
myObj2.text = &quot;hi&quot;;
myObj2.language = &quot;en&quot;;
myObj2.item = &quot;1&quot;;
MyClass myObj3 = new MyClass();
myObj3.text = &quot;holaa&quot;;
myObj3.language = &quot;es&quot;;
myObj3.item = &quot;2&quot;;
MyClass myObj4 = new MyClass();
myObj4.text = &quot;olaaaaa&quot;;
myObj4.language = &quot;pt-br&quot;;
myObj4.item = &quot;2&quot;;
MyClass myObj5 = new MyClass();
myObj5.text = &quot;helllooo&quot;;
myObj5.language = &quot;eng&quot;;
myObj5.item = &quot;3&quot;;
List&lt;MyClass&gt; lang = new ArrayList&lt;MyClass&gt;();
lang.add(myObj1);
lang.add(myObj2);
lang.add(myObj3);
lang.add(myObj3);
lang.add(myObj4);
ArrayList&lt;HashMap&lt;String, String&gt;&gt; lista = new ArrayList&lt;&gt;();
HashMap&lt;String, String&gt; mapa = new HashMap&lt;&gt;();
for(int i = 0; i &lt; lang.size();i++) {
if(i &gt; 0 &amp;&amp; lang.get(i).item != lang.get(i-1).item) {
lista.add(mapa);
mapa.clear();
}
if(i == lang.size()-1){
lista.add(mapa);
mapa.clear();
}
mapa.put(lang.get(i).language, lang.get(i).text); 
}
System.out.println(lista.toString());
}
}

which should be returned in this pattern:

[{
&quot;item_id&quot;: 1,
&quot;language&quot;: [{
&quot;pt-br&quot;: &quot;ola&quot;,
&quot;en&quot;: &quot;hii&quot;
}]
}, {
&quot;item_id&quot;: 2,
&quot;language&quot;: [{
&quot;es&quot;: &quot;holaa&quot;,
&quot;pt-br&quot;: &quot;olaaaaa&quot;
}]
}, {
&quot;item_id&quot;: 3,
&quot;language&quot;: [{
&quot;eng&quot;: &quot;helllooo&quot;
}]
}]

the whole part of Spring is already implemented, I need to manipulate the result so that it is displayed correctly in my endpoint.

答案1

得分: 1

以下是翻译好的内容:

值得实现一个 Item 对象,然后将输入的 List&lt;MyClass&gt; lang 转换为 List&lt;Item&gt;

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Item {
    int item_id;
    List&lt;Map&lt;String, String&gt;&gt; language; // 或许 Map&lt;String, String&gt; 更适合

    Item(Map.Entry&lt;Integer, Map&lt;String, String&gt;&gt; entry) {
        this(entry.getKey(), entry.getValue());
    }
    
    Item(int id, Map&lt;String, String&gt; language) {
        this.item_id = id;
        this.language = Arrays.asList(language);
    }
    
    public String toString() {
        return String.format("item_id: %d,%nlanguage: %s%n", item_id, language);
    }
    // getters/setters
}
// MyClass.java
static List&lt;Item&gt; transform(List&lt;MyClass&gt; data) {
    return data
            .stream()
            .collect(Collectors.groupingBy(
                x -&gt; Integer.parseInt(x.item), // 转为 int `item_id`
                LinkedHashMap::new,            // 保持插入顺序
                Collectors.mapping(            // 准备 map language:text
                    x -&gt; Map.entry(x.language, x.text),  // Java 9
                    Collectors.toMap(
                        Map.Entry::getKey, 
                        Map.Entry::getValue, 
                        (a, b) -&gt; a,           // 合并偶尔重复项
                        LinkedHashMap::new)    // 保持插入顺序或使用 TreeMap 按语言排序
                    )
            ))
            .entrySet().stream()
            .map(Item::new)  // 引用重载构造函数
            .collect(Collectors.toList());
}

测试

List&lt;Item&gt; items = transform(lang);
items.forEach(System.out::println);

输出

item_id: 1,
language: [{pt-br=ola, en=hi}]

item_id: 2,
language: [{es=holaa, pt-br=olaaaaa}]

item_id: 3,
language: [{eng=helllooo}]

备注:

  • 如果不能使用 Java 9 的 Map.entry,可以用旧的 new AbstractMap.SimpleEntry(x.language, x.text) 来替代。
  • 不确定 Item 中是否真的需要列表映射,只是为了满足要求而提供的,Arrays.asList(e.getValue()) 也是如此;映射实例应该足够了。
  • Item 类中,使用 Jackson 的 @JsonNaming 注解和 SnakeCaseStrategy 来确保 item_id 的正确序列化。

更新
Item 类中进行了修复并添加了一个重载的构造函数,在 transform 中使用了方法引用 Item::new

英文:

It is worth to implement an Item object and then transform the input List&lt;MyClass&gt; lang into List&lt;Item&gt;:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Item {
    int item_id;
    List&lt;Map&lt;String, String&gt;&gt; language; // perhaps Map&lt;String, String&gt; would do fine

    Item(Map.Entry&lt;Integer, Map&lt;String, String&gt;&gt; entry) {
        this(entry.getKey(), entry.getValue());
    }
    
    Item(int id, Map&lt;String, String&gt; language) {
        this.item_id = id;
        this.language = Arrays.asList(language);
    }
    
    public String toString() {
        return String.format(&quot;item_id: %d,%nlanguage: %s%n&quot;, item_id, language);
    }
    // getters/setters
}
// MyClass.java
static List&lt;Item&gt; transform(List&lt;MyClass&gt; data) {
    return data
            .stream()
            .collect(Collectors.groupingBy(
                x -&gt; Integer.parseInt(x.item), // to become int `item_id`
                LinkedHashMap::new,            // keep insertion order 
                Collectors.mapping(            // prepare map language:text
                    x -&gt; Map.entry(x.language, x.text),  // Java 9
                    Collectors.toMap(
                        Map.Entry::getKey, 
                        Map.Entry::getValue, 
                        (a, b) -&gt; a,           // merge occasional duplicates
                        LinkedHashMap::new)    // keep insertion order or TreeMap to sort by language
                    )
            ))
            .entrySet().stream()
            .map(Item::new)  // referencing overloaded constructor
            .collect(Collectors.toList());
}

Test

List&lt;Item&gt; items = transform(lang);
items.forEach(System.out::println);

Output

item_id: 1,
language: [{pt-br=ola, en=hi}]
item_id: 2,
language: [{es=holaa, pt-br=olaaaaa}]
item_id: 3,
language: [{eng=helllooo}]

Comments:

  • if Java 9 Map.entry cannot be used, it may be replaced with older new AbstractMap.SimpleEntry(x.language, x.text)
  • not sure whether list of maps is really needed in Item, it is provided just to meet the requirement as well as Arrays.asList(e.getValue()); the map instance should be fine.
  • in Item class use Jackson SnakeCaseStrategy in @JsonNaming annotation to guarantee proper serialization of item_id.

Update<br/>
Fixed and added an overloaded constructor in Item class, used method reference Item::new in transform

huangapple
  • 本文由 发表于 2020年10月27日 05:46:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64545435.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定