英文:
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 = "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());
}
}
which should be returned in this pattern:
[{
"item_id": 1,
"language": [{
"pt-br": "ola",
"en": "hii"
}]
}, {
"item_id": 2,
"language": [{
"es": "holaa",
"pt-br": "olaaaaa"
}]
}, {
"item_id": 3,
"language": [{
"eng": "helllooo"
}]
}]
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<MyClass> lang
转换为 List<Item>
:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Item {
int item_id;
List<Map<String, String>> language; // 或许 Map<String, String> 更适合
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), // 转为 int `item_id`
LinkedHashMap::new, // 保持插入顺序
Collectors.mapping( // 准备 map language:text
x -> Map.entry(x.language, x.text), // Java 9
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(a, b) -> a, // 合并偶尔重复项
LinkedHashMap::new) // 保持插入顺序或使用 TreeMap 按语言排序
)
))
.entrySet().stream()
.map(Item::new) // 引用重载构造函数
.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
类中,使用 Jackson 的@JsonNaming
注解和SnakeCaseStrategy
来确保item_id
的正确序列化。
更新
在 Item
类中进行了修复并添加了一个重载的构造函数,在 transform
中使用了方法引用 Item::new
。
英文:
It is worth to implement an Item
object and then transform the input List<MyClass> lang
into List<Item>
:
@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());
}
Test
List<Item> 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 oldernew 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 asArrays.asList(e.getValue())
; the map instance should be fine. - in
Item
class use JacksonSnakeCaseStrategy
in@JsonNaming
annotation to guarantee proper serialization ofitem_id
.
Update<br/>
Fixed and added an overloaded constructor in Item
class, used method reference Item::new
in transform
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论