Join a list of object's properties into a String

China☆狼群 提交于 2019-12-04 16:30:25

问题


I'm learning lambda right now, and I wonder how can I write this code by a single line with lambda.

I have a Person class which includes an ID and name fields

Currently, I have a List<Person> which stores these Person objects. What I want to accomplish is to get a string consisting of person's id just like.

"id1,id2,id3".

How can I accomplish this with lambda?


回答1:


To retrieve a String consisting of all the ID's separated by the delimiter "," you first have to map the Person ID's into a new stream which you can then apply Collectors.joining on.

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

if your ID field is not a String but rather an int or some other primitive numeric type then you should use the solution below:

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



回答2:


stream to map, and collect to list!

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

if you need that in a String object then join the list

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



回答3:


Slightly over-engineered, but helpful to have if this issue occurs more often (especially if you add overloaded methods that delegate to this one using default mappers and separators):

/**
 * @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));
}

and the appropriate inverse funtion:

/**
 * @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));
}

If performance is an issue I would opt for the classic loop approach:

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

and:

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



回答4:


You can also using Collectors#mapping as below:

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

OR Person.ID is not an instance of CharSequence then you need double mapping as below:

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


来源:https://stackoverflow.com/questions/44245790/join-a-list-of-objects-properties-into-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!