英文:
How to convert text to pojo by SEPARATOR
问题
Sure, here's the translation of the code-related parts you provided:
我有一个字符串文本,其格式如 `CODE@NAME`,而 `NAME` 可能为空,就像下面的文本一样:
202304110940436402@SHX01,202304110940477328@,202304110940494662@SHXZ20
POJO(Plain Old Java Object)类:
```java
public class Project {
String code;
String name;
String type;
String model;
// 其他属性
// getter 和 setter 方法
}
我将字符串转换为 Project
类对象的方式如下:
String text = "202304110940436402@SHX01,202304110940477328@,202304110940494662@SHXZ20";
Optional<List<Project>> optional = Optional.of(text)
.map(s -> s.split(COMMA))
.map(list -> {
List<Project> projects = new ArrayList<>(list.length);
for (String pojo : list) {
String[] split = pojo.split(AT, -1);
Project project = new Project();
project.code = split[0];
project.name = split[1];
projects.add(project);
}
return projects;
});
List<Project> projects = optional.orElse(null);
现在的问题是字符串文本的格式已经改变(例如 CODE@NAME@TYPE@MODEL
)。
现在的文本如下:
202304110940436402@JCSH001,202304110940477328@CGXZ01@8,202304110940494662@@46,202304111152056491@CGXZ01@8@REPEAT, 202304101953270605@XCG@23@
我希望能够解析它并以如下方式处理:
202304110940436402@JCSH001 -> code:202304110940436402,name:JCSH001
202304110940477328@CGXZ01@8 -> code:202304110940477328,name:CGXZ01,type:8
202304110940494662@@46 -> code:202304110940494662,name:,type:46
202304111152056491@CGXZ01@8@REPEAT -> code:202304111152056491,name:CGXZ01,type:8, model:REPEAT
我不知道如何解决这个问题,是否有任何简单的方法来转换它并且与之前的内容兼容?
<details>
<summary>英文:</summary>
I have a string text, the formatter like `CODE@NAME`, and the `NAME` maybe a null value, just like below text:
202304110940436402@SHX01,202304110940477328@,202304110940494662@SHXZ20
The pojo:
```java
public class Project {
String code;
String name;
String type;
String model;
// other property
// getter and setter
}
I convert string to 'Project' like this:
String text = "202304110940436402@SHX01,202304110940477328@,202304110940494662@SHXZ20";
Optional<List<Project>> optional = Optional.of(text)
.map(s -> s.split(COMMA))
.map(list -> {
List<Project> projects = new ArrayList<>(list.length);
for (String pojo : list) {
String[] split = pojo.split(AT, -1);
Project project = new Project();
project.code = split[0];
project.name = split[1];
projects.add(project);
}
return projects;
});
List<Project> projects = optional.orElse(null);
The question is that the string text changed now(such like CODE@NAME@TYPE@MODEL
).
Now the text like this:
202304110940436402@JCSH001,202304110940477328@CGXZ01@8,202304110940494662@@46,202304111152056491@CGXZ01@8@REPEAT, 202304101953270605@XCG@23@
I want to parse it like:
202304110940436402@JCSH001 -> code:202304110940436402,name:JCSH001
202304110940477328@CGXZ01@8 -> code:202304110940477328,name:CGXZ01,type:8
202304110940494662@@46 -> code:202304110940494662,name:,type:46
202304111152056491@CGXZ01@8@REPEAT -> code:202304111152056491,name:CGXZ01,type:8, model:REPEAT
I have no clue to solve it,so is there have any simple way to convert it and also compatible with previous content?
答案1
得分: 0
我认为你已经走在了正确的道路上,可能只是有些过于深思熟虑。
如果我理解正确,你想将一个逗号分隔的数组解析成一个字符串列表,然后将这些字符串解析成用 "@" 分隔的字符串。
在原始版本中,我们有 CODE@NAME 字符串,后来发生了一个变化,变成了 CODE@NAME@TYPE@MODEL。
你已经有了获取所需数据的方法,也就是在 "@" 上进行拆分。你需要检查从该拆分中得到了多少个字符串,然后将这些值赋给项目对象。
我会这样做:
Optional<List<Project>> optional = Optional.of(text)
.map(s -> s.split(COMMA))
.map(list -> {
List<Project> projects = new ArrayList<>();
for (String s: list) {
String[] split = s.split(AT);
Project project = null;
if (split.length == 2) {
project = new Project();
project.setCode(split[0]);
project.setName(split[1]);
} else if (split.length == 4) {
project = new Project();
project.setCode(split[0]);
project.setName(split[1]);
project.setType(split[2]);
project.setModel(split[3]);
}
if(project != null) projects.add(project);
}
return projects;
});
有更高效和更漂亮的代码路径可以选择,但我认为你现在可能需要冗长的代码,因为你还在学习。希望这能对你有所帮助!
英文:
I think you are on the right path already and are probably overthinking things.
If I understand it correctly you want to parse a comma seperated array into a list of String and parse said Strings into @ seperated Strings.
In the original version we have the CODE@NAME String, later there was a change where it was CODE@NAME@TYPE@MODEL.
You already have the data to get where you need to go, namely your split on @. You need to check how many Strings come out of that split and than assign your values to the Project object.
What I would do is this:
Optional<List<Project>> optional = Optional.of(text)
.map(s -> s.split(COMMA))
.map(list -> {
List<Project> projects = new ArrayList<>();
for (String s: list) {
String[] split = s.split(AT);
Project project = null;
if (split.length == 2) {
project = new Project();
project.setCode(split[0]);
project.setName(split[1]);
} else if (split.length == 4) {
project = new Project();
project.setCode(split[0]);
project.setName(split[1]);
project.setType(split[2]);
project.setModel(split[3]);
}
if(project != null) projects.add(project);
}
There are more efficient and prettier code paths to take but I think what you need right now is verbosity since you are still learning. Hope this can help!
答案2
得分: 0
你也可以使用正则表达式匹配来提取数值。例如:
```final Pattern p = Pattern.compile("^([^@]*)(?:(?:@([^@]*))?(?:(?:@([^@]*))?(?:(?:@([^@]*))?))$");
String text = "202304110940436402@JCSH001,202304110940477328@CGXZ01@8,202304110940494662@@46,202304111152056491@CGXZ01@8@REPEAT, 202304101953270605@XCG@23@";
List<Project> projects = Stream.of(Optional.of(text).orElse("").split(",")).map(s -> {
Matcher m = p.matcher(s);
if (m.find()) {
Project proj = new Project();
proj.code = m.group(1); //假设代码始终存在
proj.name = m.group(2); //假设名称始终存在
if (m.groupCount() > 2) {
proj.type = m.group(3);
if (m.groupCount() > 3) {
proj.model = m.group(4);
}
}
return proj;
} else {
return null;
}
}).filter(Objects::nonNull).toList();
这将产生类似以下的结果 - 将项目转换为JSON对象:
[
{
"code": "202304110940436402",
"name": "JCSH001",
"type": "null",
"model": "null"
},
{
"code": "202304110940477328",
"name": "CGXZ01",
"type": "8",
"model": "null"
},
{
"code": "202304110940494662",
"name": "",
"type": "46",
"model": "null"
},
{
"code": "202304111152056491",
"name": "CGXZ01",
"type": "8",
"model": "REPEAT"
},
{
"code": "202304101953270605",
"name": "XCG",
"type": "23",
"model": ""
}
]
你可以进一步优化。
<details>
<summary>英文:</summary>
You can also use Regular Expression matching to extract values. E.g.
final Pattern p = Pattern.compile("^([^@]*)(?:(?:@([^@]*))?(?:(?:@([^@]*))?(?:(?:@([^@]*))?)))$");
String text = "202304110940436402@JCSH001,202304110940477328@CGXZ01@8,202304110940494662@@46,202304111152056491@CGXZ01@8@REPEAT, 202304101953270605@XCG@23@";
List<Project> projects = Stream.of(Optional.of(text).orElse("").split(",")).map(s -> {
Matcher m = p.matcher(s);
if (m.find()) {
Project proj = new Project();
proj.code = m.group(1); //Assuming code will always be there
proj.name = m.group(2); //Assuming name will always be there
if (m.groupCount() > 2) {
proj.type = m.group(3);
if (m.groupCount() > 3) {
proj.model = m.group(4);
}
}
return proj;
} else {
return null;
}
}).filter(Objects::nonNull).toList();
This results in something like this - Converted Project into a JSON object:
[
{
"code": "202304110940436402",
"name": "JCSH001",
"type": "null",
"model": "null"
},
{
"code": "202304110940477328",
"name": "CGXZ01",
"type": "8",
"model": "null"
},
{
"code": "202304110940494662",
"name": "",
"type": "46",
"model": "null"
},
{
"code": "202304111152056491",
"name": "CGXZ01",
"type": "8",
"model": "REPEAT"
},
{
"code": " 202304101953270605",
"name": "XCG",
"type": "23",
"model": ""
}
]
You can enhance further.
</details>
# 答案3
**得分**: 0
使用switch
根据长度:
List<Project> projects = Arrays.stream(text.split(COMMA))
.map(s -> s.split(AT))
.map(arr -> {
Project project = new Project();
switch (arr.length) {
case 4: project.setModel(arr[3]);
case 3: project.setType(arr[2]);
case 2: project.setName(arr[1]);
case 1: project.setCode(arr[0]);
}
return project;
})
.collect(toList());
这很好地利用了switch
的fall through行为。
如果没有项目,您不需要Optional
- 结果列表将为空。
<details>
<summary>英文:</summary>
Use a `switch` on the length:
List<Project> projects = Arrays.stream(text.split(COMMA))
.map(s -> s.split(AT))
.map(arr -> {
Project project = new Project();
switch (arr.length) {
case 4: project.setModel(arr[3]);
case 3: project.setType(arr[2]);
case 2: project.setName(arr1);
case 1: project.setCode(arr[0]);
}
return project;
})
.collect(toList());
This makes good use of the [*fall through*][1] behaviour of the switch.
You don't need `Optional` - the resulting list will be empty if there are no items.
[1]: https://www.javatpoint.com/fall-through-in-java
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论