4

I have an ArrayList of User objects. Now I need the ArrayList of these user's names only. Is there a way to use toString() on entire ArrayList and convert it to ArrayList of String names rather than doing this in for loop? I have also overridden toString in User class so it returns user's name, and I have tried ArrayList <String> names = usersList.toString() but it didn't work.

4 Answers 4

7

You can do this using the Google Collections API:

List<User> userList = ...;
List<String> nameList = Lists.transform(userList, new Function<User, String>() {
   public String apply(User from) {
      return from.toString(); // or even from.getName();
   }
});

The library has been renamed to Guava.


With Java 8, using streams and method references you can now achieve the same thing even without using Guava:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class User {

    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class App {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>(Arrays.asList(
                new User("Alan Turing"),
                new User("John von Neumann"),
                new User("Edsger W Dijkstra")
        ));

        List<String> names = users
                .stream()
                .map(User::getName)
                .collect(Collectors.toList());

        System.out.println(names);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Can be shortened to List<String> nameList = Lists.transform(userList, Functions.toStringFunction());, as long as you stick to toString (instead of the suggested getName).
How to convert the same for ArrayList<String> to ArrayList<Object[]>
@Subra: ArrayList<String> stringList = ...; ArrayList<Object[]> objectArrayList = Lists.transform(stringList, new Function<String, Object[]>() { public Object[] apply(String from) { return new Object[] { from }; } });
Thanks you. This is Awesome. Spent hell 5 years of coding without this.
@sha You are welcome! :) I added a version that uses new Java 8 features that doesn't depend on Guava anymore.
6

The Object#toString() returns a String, not an ArrayList. That's your problem. You really need to loop over it. There's absolutely no reason for an aversion against looping. Just hide it away in some utility method if the code is bothering you somehow ;)


With Java 8, you can use lambda expressions, streams, and method references to simplify your code.

The following

List<User> users = getItSomehow();
List<String> names = new ArrayList<String>();
for (User user : users) {
    names.add(user.getName());
}

can then be shortened to like

List<User> users = getItSomehow();
List<String> names = users.stream().map(User::getName).collect(Collectors.toList());

By the way, you can also put the for in a single line:

for (User user : users) names.add(user.getName());

It may however not be directly understandable for starters.

2 Comments

BalusC: I updated your answer and added the Java 8 implementation. Originally it had one of the proposed specifications for adding closures and lambda expressions to Java 7 that changed significantly when it finally got introduced to Java 8.
@Behrang: yep, already noticed it and fixed the style and typo.
1

In a word: No. What you need is a map function, which you don't have in Java (yet, as BalusC points out). You can write something similar yourself, but you'll end up iterating over each element in your List regardless.

Comments

0
public ArrayList< String > toStringList( Collection< MyObject > objectList )
{
    ArrayList< String > stringList = new ArrayList< String >();

    for( MyObject myobj : objectList ) {
        stringList.add( myobj.toString() );
    }

    return stringList;
}

...

ArrayList< String > myStringList = toStringList( objectList );

There. One line, and you can reuse it with whatever collection of objects you have in the future.

2 Comments

I mentioned I was wondering if it is possible without using for loop, something like stringList.addAll(objectList.toString() )
@Mike55 Why avoid the for loop? Even if you write this in such a way where you don't use a for-loop, by using a library call like Guava, at some point some piece of code must still visit every element in the list to transform it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.