0

I have to get a List of strings from a List of Objects, and I don't think looping through it is the best way.

Explanation:

With Person being:

public class Person{
    String name;
    String id;
}

I have a List of as parameter to a method

public List<String> getNames(ArrayList<Person> people){}

And I want the list of names in the list of people

what's the best way to do that without looping and adding to another List?

5
  • Why don't you want a List<String to be returned? Commented Nov 28, 2018 at 13:10
  • I do, just forgot to put it on the method declaration, already edited it, thanks! Commented Nov 28, 2018 at 13:11
  • 1
    Next question would be why not loop over? It will be done regardless which approach you want to take. Commented Nov 28, 2018 at 13:12
  • actually I always do it by looping, but I was wondering if there was a better way of doing it Commented Nov 28, 2018 at 13:16
  • @CarlosMion in which case you mean you’ve always “externally” iterated over the collection. Like Murat mentioned whichever approach you take there will be some sort of iteration whether that is internal iteration (which is what you seem to be looking for) or external iteration (which seems like is what you want to avoid). Commented Nov 28, 2018 at 14:22

5 Answers 5

2

If you are allowed to use java 8 in android you can simply do a map over your list:

public List<String> getNames(ArrayList<Person> people){
    return people.stream().map(a -> a.name).collect(Collectors.toList());
}
Sign up to request clarification or add additional context in comments.

4 Comments

You can use retrolambda, It is quite popular : github.com/evant/gradle-retrolambda
+1 for Stream and Lambda. OP should use Java8 or just iterate over his List. There's nothing wrong about looping.
@JohnDoe OP is using android and most likely below the min API level for the stream api.
exactly, I'm programming for corporate old devices
1
public class Person{
    String name;
    String id;

    @Override
    public String toString() {
        return name;
    }
}

In methods

public List<String> getNames(ArrayList<Person> people){
    return Arrays.asList((people.toString().replace("[","").replace("]","")).split(Pattern.quote(",")));
}

Comments

0

This is probably the answer you're looking for:

System.out.println(Arrays.DeeptoString(people))

2 Comments

and how do I decide which String from the Object to get?
If you add each variable to separate array lists prior to calling your method, you can simply println the list to console (as shown above). If not, however, the easiest method would be to loop and then choose the variable to display.
0

what's the best way to do that without looping and adding to another List?

Converting one Iterable to another Iterable will involve looping.

You could store the names in another ArrayList<String> while creating original ArrayList<Person> but the advantage over simply looping over Persons is highly questionable.

Comments

0

If you don't want to iterate over List<Persons> people you could create a view on the list, which will show a Person in a specific way.

public class ListView<L, T> extends AbstractList<T> {

    private List<L> original;
    private Mapper<L, T> mapper;

    private ListView(List<L> original, Mapper<L, T> mapper) {
        this.original = original;
        this.mapper = mapper;
    }

    @Override
    public T get(int index) {
        return mapper.map(original.get(index));
    }

    @Override
    public int size() {
        return original.size();
    }

    private static <L, T> ListView<L, T> of(List<L> original, Mapper<L, T> mapper) {
        return new ListView<>(original, mapper);
    }

}

A Mapper is an interface and defines how we want to view a Person.

private static abstract interface Mapper<I, O> {

    O map(I input);

}

Now we can use this to implement getNames:

public List<String> getNames(ArrayList<Person> people) {
    return ListView.of(people, new Mapper<Person, String>() {

        @Override
        public String map(Person person) {
            return person.getName();
        }
    });
}

Applied to an example:

ArrayList<Person> people = new ArrayList<>(Arrays.asList(new Person("Micky", "1"), new Person("Donald", "2"), new Person("Daisy", "3")));
List<String> names = getNames(people);
System.out.println(names); // [Micky, Donald, Daisy]

Please note: The shown implementation of ListView does not support modification. Thus it's a read only List. If you don't want to add a name without adding a Person then this implementation should be sufficient.

Using Java 8 would result in much simpler code. But you said you cannot. Thus this approach without Java 8 features.

Comments

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.