【问题标题】:Java ArrayList of hasMap to return in Spring endpoint在 Spring 端点中返回的 hashMap 的 Java ArrayList
【发布时间】:2020-10-26 21:46:39
【问题描述】:

我有一些示例对象将包含在一个 ArrayList 中,这些项目必须以特定格式出现,每个 item 必须是一个数组在 json 中的新位置返回。

按照我目前开发的代码:

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, String>> lista = new ArrayList<>();
        
        HashMap<String, String> mapa = new HashMap<>();
        
        for(int i = 0; i < lang.size();i++) {
            
            
            if(i > 0 && 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());
        
    }
}

应该以这种模式返回:

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

Spring 的整个部分已经实现,我需要对结果进行操作,以便它在我的端点中正确显示。

【问题讨论】:

  • 现在有什么问题?
  • 我无法在数组列表的同一位置返回每个 item_id
  • 如果每个项目的language 属性总是包含一个对象,它是否必须是一个数组?
  • 是的,一个数组..
  • 输入数组中的项目是否总是保证从1、2、3、...到n?其中 n 是项目总数。或者是否有间隙,例如输入数组只有第 1、3 和 5 项。

标签: java spring arraylist hashmap


【解决方案1】:

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

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

    Item(Map.Entry<Integer, Map<String, String>> entry) {
        this(entry.getKey(), entry.getValue());
    }
    
    Item(int id, Map<String, String> 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<Item> transform(List<MyClass> data) {
    return data
            .stream()
            .collect(Collectors.groupingBy(
                x -> Integer.parseInt(x.item), // to become int `item_id`
                LinkedHashMap::new,            // keep insertion order 
                Collectors.mapping(            // prepare map language:text
                    x -> Map.entry(x.language, x.text),  // Java 9
                    Collectors.toMap(
                        Map.Entry::getKey, 
                        Map.Entry::getValue, 
                        (a, b) -> 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());
}

测试

List<Item> 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 类中使用@JsonNaming 注释中的Jackson SnakeCaseStrategy 以保证item_id 的正确序列化。

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

【讨论】:

    猜你喜欢
    • 2016-07-21
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多