将对象属性列表加入字符串

Posted

技术标签:

【中文标题】将对象属性列表加入字符串【英文标题】:Join a list of object's properties into a String 【发布时间】:2017-10-29 22:58:57 【问题描述】:

我现在正在学习 lambda,不知道如何用 lambda 一行代码来写这段代码。

我有一个 Person 类,其中包括一个 IDname 字段

目前,我有一个 List<Person> 来存储这些 Person 对象。我想要完成的是得到一个由人的 id 组成的字符串。

“id1,id2,id3”

我怎样才能用 lambda 完成这个?

【问题讨论】:

【参考方案1】:

要检索由分隔符 "," 分隔的所有 ID 组成的 String,您首先必须将 mapPerson ID 放入一个新流中,然后您可以在该流上应用 Collectors.joining

String result = personList.stream().map(Person::getId)
                          .collect(Collectors.joining(","));

如果您的 ID 字段不是 String 而是 int 或其他一些原始数字类型,那么您应该使用以下解决方案:

String result = personList.stream().map(p -> String.valueOf(p.getId()))
                          .collect(Collectors.joining(","));

【讨论】:

.map(Person::getId).map(String::valueOf)【参考方案2】:

流到地图,收集到列表!

List<String> myListofPersons = personList.stream()
          .map(Person::getId)
          .collect(Collectors.toList());

如果您在 String 对象中需要它,则加入列表

String res = String.join(" , ", myListStringId);
System.out.println(res);

【讨论】:

结果是List,但是我想要的是一个字符串【参考方案3】:

稍微过度设计,但如果这个问题更频繁地发生(特别是如果您添加使用默认映射器和分隔符委托给该问题的重载方法时)会有帮助:

/**
 * @param separator used to join the values. NOTE: the separator is interpreted as a regular expression.
 * @return a list of the values' string representation according to <code>mapper</code>, separated by the specified
 *         string. Null if list is null or empty.
 */
public static <R> String toListString(Collection<R> list, String separator,
                                      Function<? super R, ? extends String> mapper)

    if (list == null || list.isEmpty())
    
        return null;
    

    return list.stream()
               .map(mapper)
               .collect(Collectors.joining(separator));

以及相应的反函数:

/**
 * @param list a list of values, separated by the specified separator
 * @param separator used to join the values. NOTE: the separator is interpreted as a regular expression.
 * @param mapper the function to map a single string to a value.
 * @return a list of the values. Empty if string is null or empty.
 */
public static <R> List<R> fromListString(String list, String separator,
                                         Function<? super String, ? extends R> mapper)

    if (list == null || list.isEmpty())
    
        return new ArrayList<>();
    

    return Arrays.stream(list.trim().split(separator))
                 .map(mapper)
                 .collect(Collectors.toCollection(ArrayList::new));

如果性能是一个问题,我会选择经典循环方法:

    StringBuilder s = new StringBuilder();
    for(R r : list)
        if (s.length() != 0)
            s.append(separator);
        s.append(mapper.apply(r));
    
    return s.toString();

和:

    List<R> result = new ArrayList<>();
    for (String s : list.trim().split(separator))
        result.add(mapper.apply(s));
    
    return result;

【讨论】:

【参考方案4】:

您也可以使用Collectors#mapping,如下:

String ids = personList.stream().collect(mapping(Person::getId
      , Collectors.joining(",")));

OR Person.ID 不是CharSequence 的实例,那么您需要如下双重映射:

String ids = personList.stream().collect(mapping(Person::getId
    , mapping(String::valueOf
        , Collectors.joining(","))));

【讨论】:

以上是关于将对象属性列表加入字符串的主要内容,如果未能解决你的问题,请参考以下文章

C#如何将变量用作键值字符串数组的对象列表对象构造函数中的属性名称

加入列表和拆分字符串 [重复]

C# - 将对象列表转换为包含多个对象属性的数组

将字符串保存到属性列表(plist)文件?

如何将列表加入字符串(警告)?

列表,元组,字典类的常见简单方法