2

I have to create a result list by adding objects from one array list to another. Here is my code that works.

    private List<MyObject> getObjectList(List<OtherObject> objects) {
        List<MyObject> resultList = new ArrayList<>();
        for (int i = 0; i < objects.size(); i++) {
        MyObject object = new MyObject()
            object.setId(objects.get(i).getId());
            object.setText(objects.get(i).getTextValue());
            object.setUserId(objects.get(i).getUserName());
            object.setCreatedDate(objects.get(i).getCreateDateTime());

            resultList.add(object);
        }
        
        return resultList;
    }

How can I achieve this by using lambda expression?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
iranichai
  • 363
  • 1
  • 6
  • 19
  • 1
    Your loop solution can be significantly improved by using a [for-each loop](https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html) – Hulk Oct 05 '20 at 15:37
  • 2
    And using Builder or Constructor make it better. – Eklavya Oct 05 '20 at 15:38
  • 1
    With "using lambda expression", I assume you mean using [Stream](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/stream/Stream.html)? – Hulk Oct 05 '20 at 15:38
  • Does this answer your question? [How to clone ArrayList and also clone its contents?](https://stackoverflow.com/questions/715650/how-to-clone-arraylist-and-also-clone-its-contents) – Hulk Oct 05 '20 at 15:44
  • 1
    In your case it's not a straight-forward copy, as you are mapping to a different element type, but the basics are the same. I'd write either a constructor for `MyObject` that accepts a `OtherObject`. – Hulk Oct 05 '20 at 15:48

3 Answers3

3

Here's how you can do it with a method reference:

private List<MyObject> getObjectList(List<OtherObject> objects) {
    return objects.stream()
        .map(this::map)
        .collect(Collectors.toList());
}

private MyObject map(OtherObject otherObject) {
    MyObject object = new MyObject();
    object.setId(otherObject.getId());
    object.setText(otherObject.getTextValue());
    object.setUserId(otherObject.getUserName());
    object.setCreatedDate(otherObject.getCreateDateTime());
    return object;
}

Here's how you can do it using streams and lambda expression:

private List<MyObject> getObjectList(List<OtherObject> objects) {
    return objects.stream()
        .map(obj -> {
        MyObject object = new MyObject();
        object.setId(obj.getId());
        object.setText(obj.getTextValue());
        object.setUserId(obj.getUserName());
        object.setCreatedDate(obj.getCreateDateTime());
        return object;
    }).collect(Collectors.toList());
}
George
  • 2,820
  • 4
  • 29
  • 56
1

Here is an example:

    private List<MyObject> getObjectList(List<OtherObject> objects) {
        List<MyObject> resultList = new ArrayList<>();
        objects.forEach(obj -> {
            MyObject object = new MyObject();
            object.setId(obj.getId());
            object.setText(obj.getTextValue());
            object.setUserId(obj.getUserName());
            object.setCreatedDate(obj.getCreateDateTime());
            resultList.add(object);
        });
        return resultList;
    }
ollitietavainen
  • 3,900
  • 13
  • 30
  • 3
    `.stream()` is redundant if you're going to use the terminating operator `forEach()` anyways. `objects.forEach(` would suffice. – George Oct 05 '20 at 15:50
  • Edited to `objects.forEach()` – ollitietavainen Oct 05 '20 at 15:54
  • But still, mutating external state in a stream is considered an anti-pattern; that is better done via reduction, or in this case, the special form of reduction called collection. Here is some more information: https://developer.ibm.com/articles/j-java-streams-2-brian-goetz/ – erickson Oct 05 '20 at 16:29
0

Using Record

Equivalent of your OtherObject

import java.time.LocalDateTime;

public record OtherRec(int            id,
                       String         textValue,
                       String         userName,
                       LocalDateTime  createDateTime) {
}

Equivalent of your MyObject

import java.time.LocalDateTime;

public record MyRecord(int id,
                       String text,
                       String userId,
                       LocalDateTime createDate) {
}

Copying list of OtherRec to MyRecord

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

public class CopyList {

    public static void main(String[] args) {
        List<OtherRec> source = List.of(new OtherRec(1, "First", "One", LocalDateTime.of(2020, 10, 5, 12, 0)),
                                        new OtherRec(2, "Second", "Two", LocalDateTime.of(2020, 10, 5, 13, 0)));
        List<MyRecord> target = source.stream()
                                      .map(or -> new MyRecord(or.id(), or.textValue(), or.userName(), or.createDateTime()))
                                      .collect(Collectors.toList());
        System.out.println(target);
    }
}
Abra
  • 19,142
  • 7
  • 29
  • 41