-1

I have a lot of OrderDTO objects in the list.

Example with 2 items:

final List<OrderDTO> orderList = new ArrayList<OrderDTO>();

final List<OrderDTO> orderList = new ArrayList<OrderDTO>();
final OrderDTO order1 = new OrderDTO("1", "100");
final OrderDTO order2 = new OrderDTO("2", "200");
orderList.add(order1);
orderList.add(order2);

OrderDTO has fields, for example orderId and stateId.

I want to show in log:

"1", "2" 

or

"100", "200"

In Java 11, what is the most efficient way to iterate the list and show values of one field of every object?

Holger
  • 285,553
  • 42
  • 434
  • 765
davidleongz
  • 155
  • 2
  • 11
  • 2
    Iterate on the list and print... It's a linear operation, there's not much room for improvement here. Unless you parallelize things but I'm afraid the IO will still be a bottleneck – Federico klez Culloca Mar 18 '21 at 10:13
  • You can use stream, transform OrderDTO to OrderDTO::get... after that use forEach to write values in log – JHDev Mar 18 '21 at 10:14
  • According to the first hit in google (but for Java7) https://howtodoinjava.com/java/collections/performance-comparison-of-different-for-loops-in-java/ it was iterating it from the end – wawek Mar 18 '21 at 10:16
  • 2
    @wawek in that article you linked is an error, the last option won't iterate even once, the condition should be `j > 0` instead of `j > size`. No wonder it's the fastest. I won't even start on the fact that it's not how you do microbenchamarks in java ([How do I write micro-benchmarks?](https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java)). – Amongalen Mar 18 '21 at 10:26
  • 1
    Did you mean "what is the most efficient" or did you mean "what's the cleanest looking code"? [cause you tagged streams - but a simple for loop is way the most efficient if you are just generating value of 1 field on every object]. – Mr R Mar 18 '21 at 10:28
  • @FedericoklezCulloca Iterating linked lists with subscripts is not a linear operation. –  Mar 18 '21 at 10:30
  • @saka1029 the sample is using `ArrayList` in the same method - you are 100% on the money in general though, although it's not clear whether @FedericoklezCulloca is talking about using an interator or doing a for-loop. – Mr R Mar 18 '21 at 10:35
  • @saka1029 that's an `ArrayList` though – Federico klez Culloca Mar 18 '21 at 10:36
  • @saka1029 There are a million ways you could implement something inefficiently. You could put a `Thread.sleep` in there for 10 years. The possibility that something can be done inefficiently does not make "how to do X efficiently" a good question. – Michael Mar 18 '21 at 10:37

2 Answers2

5

While one way of iterating over a collection might be more performant than other, in your usecase it won't matter at all. The part that takes the most time is printing the elements, not how you iterate the collection. Generally printing some output takes thousands of times longer than just iterating over a collection. If you were to just iterate over 10 million elements it could take 100ms. If you add a System.out.println inside of that loop, it might take a few minutes to execute.

In short, it is not worth thinking about optimization in your usecase.

Also, it might be worth reading about "premature optimization" - don't optimize something unless you actually see some performance problems.

Amongalen
  • 3,101
  • 14
  • 20
2

Since I was also quite confused at the beginning when I started to deal with logging and the net brought quite different results how to do it and I had a hard time to find a simple helloworld example, the following simple example might help others:

import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Example {
    private static final Logger LOG = LoggerFactory.getLogger(Example.class);
    public static void main(String[] args) {
        final List<OrderDTO> orderList = List.of(new OrderDTO("1", "100"), new OrderDTO("2", "200"));
        LOG.info("ids: {}", orderList.stream().map(OrderDTO::getOrderId).collect(Collectors.toList()));
        LOG.info("states: {}", orderList.stream().map(OrderDTO::getStateId).collect(Collectors.toList()));
    }

    @Getter
    @Setter
    @AllArgsConstructor
    private static class OrderDTO {
        String orderId;
        String stateId;
        public OrderDTO() {
        }
    }
}

Output

[main] INFO newpackage.Example - ids: [1, 2]
[main] INFO newpackage.Example - states: [100, 200]

Assuming you have added this dependencies to your pom:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.26</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.28</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <type>jar</type>
</dependency>
Eritrean
  • 15,851
  • 3
  • 22
  • 28