将文本转换为POJO对象通过分隔符。

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

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 = &quot;202304110940436402@SHX01,202304110940477328@,202304110940494662@SHXZ20&quot;;
Optional&lt;List&lt;Project&gt;&gt; optional = Optional.of(text)
        .map(s -&gt; s.split(COMMA))
        .map(list -&gt; {
            List&lt;Project&gt; projects = new ArrayList&lt;&gt;(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&lt;Project&gt; 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  -&gt; code:202304110940436402,name:JCSH001 
202304110940477328@CGXZ01@8  -&gt; code:202304110940477328,name:CGXZ01,type:8
202304110940494662@@46  -&gt; code:202304110940494662,name:,type:46
202304111152056491@CGXZ01@8@REPEAT -&gt; 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&lt;List&lt;Project&gt;&gt; optional = Optional.of(text)
            .map(s -&gt; s.split(COMMA))
            .map(list -&gt; {
                List&lt;Project&gt; projects = new ArrayList&lt;&gt;();
                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(&quot;^([^@]*)(?:(?:@([^@]*))?(?:(?:@([^@]*))?(?:(?:@([^@]*))?)))$&quot;);

	String text = &quot;202304110940436402@JCSH001,202304110940477328@CGXZ01@8,202304110940494662@@46,202304111152056491@CGXZ01@8@REPEAT, 202304101953270605@XCG@23@&quot;;
	List&lt;Project&gt; projects = Stream.of(Optional.of(text).orElse(&quot;&quot;).split(&quot;,&quot;)).map(s -&gt; {
		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() &gt; 2) {
				proj.type = m.group(3);
				if (m.groupCount() &gt; 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&lt;Project&gt; projects = Arrays.stream(text.split(COMMA))
  .map(s -&gt; s.split(AT))
  .map(arr -&gt; {
    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());

这很好地利用了switchfall 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&#39;t need `Optional` - the resulting list will be empty if there are no items.


  [1]: https://www.javatpoint.com/fall-through-in-java

</details>



huangapple
  • 本文由 发表于 2023年4月11日 11:13:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982147.html
匿名

发表评论

匿名网友

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

确定