使用流查找重复项时追加字符串

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

Appending a string when find duplicate using stream

问题

我确实有一个使用情况在这种情况下我需要将一个字符串name与版本name_version附加在一起而这个版本是我在模型层中拥有的但这仅适用于列表中重复的名称

**Student.java**

private class Student {
    private String name;
    private String value;
}

**Test.java**

public class NewTest {
    public static void main(String[] args) {

        Student s1 = new Student("xyz", "a1");
        Student s2 = new Student("abc", "a2");
        Student s3 = new Student("xyz", "a3");
        List<String> l2 = new ArrayList<>();
        List<Student> l1 = new ArrayList<Student>();
        l1.add(s1);
        l1.add(s2);
        l1.add(s3);

        // 仅获取列表中的名称
        l1.stream().forEach(e -> l2.add(e.getName()));

        // 输出为
        // {"xyz", "abc", "xyz"}

        // 仅查找重复的名称
        Set<String> result = l2.stream().filter(i -> Collections.frequency(l2, i) > 1).collect(Collectors.toSet());

        // 输出为
        // {"xyz"}

        // 不确定如何继续
        l1.stream().map(e -> {
            if (result.contains(e.getName())) {
                return e.getName() + "_" + e.getValue();
            } else {
                return e.getName();
            }
        }).forEach(System.out::println);

        // 期望输出
        // {"xyz_a1", "abc", "xyz_a3"}
    }
}

注意:代码中的翻译并不是逐字的翻译,而是根据语境进行的适当翻译,以确保代码的逻辑和含义得以保留。

英文:

I do have a use case where i need to append a string(name) with version (name_version) which i will have in a model layer. But this is to be done only for the name which are duplicate in the list.

Student.java

private class Student{
private String name;
private String value;
}

Test.java

public class NewTes {
public static void main(String[] args){
Student s1 = new Student(&quot;xyz&quot;,&quot;a1&quot;);
Student s2 = new Student(&quot;abc&quot;,&quot;a2&quot;);
Student s3 = new Student(&quot;xyz&quot;,&quot;a3&quot;);
List&lt;String&gt; l2 = new ArrayList&lt;&gt;();
List&lt;Student&gt; l1 = new ArrayList&lt;Student&gt;();
l1.add(s1);
l1.add(s2);
l1.add(s3);
//Get only names from the list
l1.stream().forEach(e -&gt; l2.add(e.getName()));
// Output is
//{&quot;xyz&quot;,&quot;abc&quot;,&quot;xyz&quot;}
//Finding only the duplicate ones
Set&lt;String&gt; result = l2.stream().filter(i -&gt; Collections.frequency(l2, i) &gt; 1).collect(Collectors.toSet());
//Output is
//{&quot;xyz&quot;}
//Not sure how to proceed from here
l1.stream().map(e -&gt; e.getName()).flatMap(x -&gt; result.contains(x) ? Stream.of(x + ))
//expected output
//{&quot;xyz_a1&quot;, &quot;abc&quot; , &quot;xyz_a3&quot;}
}
}

答案1

得分: 0

使用您之前问题中的列表,以下代码应该可以给您想要的结果 -

l1.stream()
  .map(e -> result.contains(e.getName()) ? String.join("_", e.getName(), e.getValue()) : e.getName())
  .collect(Collectors.toList());
英文:

using your previous lists from your question.. below should give you desire result -

l1.stream()
.map(e -&gt; result.contains(e.getName())? String.join(&quot;_&quot;,e.getName(),e.getValue()) : e.getName())
.collect(Collectors.toList());

答案2

得分: 0

这是一个很好的想法,可以在你的类中覆盖 equalshashCode 方法。如果你已经这样做了,以在 name 字段上进行比较,那么你就不需要使用 Set 来收集重复项。你可以按照以下方式实现:

List<String> list = l1.stream()
	.map(e -> Collections.frequency(l1, e) > 1 ?
			String.join("_", e.getName(), e.getValue()) :
			e.getName())
	.collect(Collectors.toList());

list.forEach(System.out::println);

输出结果为:

xyz_a1
abc
xyz_a3
英文:

It is a good idea to override equals and hashCode in your class. If you had done so to compare on the name field you would not need the Set to collect duplicates. You could do it as follows:

List&lt;String&gt; list = l1.stream()
.map(e -&gt; Collections.frequency(l1, e) &gt; 1 ?
String.join(&quot;_&quot;, e.getName(), e.getValue()) :
e.getName())
.collect(Collectors.toList());
list.forEach(System.out::println);

Prints

xyz_a1
abc
xyz_a3
</details>

huangapple
  • 本文由 发表于 2020年8月18日 21:35:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63469832.html
匿名

发表评论

匿名网友

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

确定