Alberto Castaño
Alberto Castaño

Reputation: 306

Map a Collection of Objects by property in Java

I have a custom Class like this:

public class Client {
    public int ID;
    public String Name;
    public double buys;
    public double getBuys() {
        return this.buys;
    }
}

Then, I have defined a list of Client, like:

List<Client> clientList;

Let's say that that List has a lot of client objects, already initialized. How can I map the field "buys" of each client object using Java 8?

I've tried something like:

List<Client> clientList2 = clientList.stream().map(c.getBuys() -> c.getBuys() + 1).collect(Collections.toList());

It, of course, isn't working, but i can't figure out (or find) any way to do it. What I want to do is just to modify every "buys" value of each object of the list. In the example case, I'm adding one, but it could be any operation.

Upvotes: 2

Views: 1217

Answers (3)

Tunaki
Tunaki

Reputation: 137104

After reading your comment, what you want is to modify the buys of each client by applying a custom function. Consider the following method:

private static List<Client> mapClients(List<Client> clients, DoubleUnaryOperator op) {
    return clients.stream()
                  .peek(c -> c.setBuys(op.applyAsDouble(c.getBuys())))
                  .collect(Collectors.toList());
}

or the following simple for loop:

private static List<Client> mapClients(List<Client> clients, DoubleUnaryOperator op) {
    for (Client client : clients) {
        client.setBuys(op.applyAsDouble(client.getBuys()))
    }
    return clients;
}

This method will mutate every Client and set the buys with the result of the operator (a DoubleUnaryOperator is an operator that takes a double as argument and returns a value of type double). The operator is getting the buys as input to make the calculation. Then, you could use it like this:

mapClients(clients, d -> d + 1); // every buys are added 1
mapClients(clients, d -> 2*d); // every buys are multiplied by 2

Note that this solution mutates an existing Object, which is not a nice practice. It would be better to have a constructor of Client taking the buys as input and mapping the result of the operation to a new Client, like this:

private static List<Client> mapClients(List<Client> clients, DoubleUnaryOperator op) {
    return clients.stream()
                  .map(c -> new Client(op.applyAsDouble(c.getBuys())))
                  .collect(Collectors.toList());
}

Upvotes: 1

Marco
Marco

Reputation: 63

Have you tried using Iterator provided by Java?

for( Client c: clientList){ 
System.out.println(c.getBuys());
}

Or add the result to a map or whatever.

Upvotes: 0

Paul Boddington
Paul Boddington

Reputation: 37645

I would just use a for loop.

for (Client client : clientList)
    client.setBuys(client.getBuys() + 1);

Upvotes: 1

Related Questions