Home > Back-end >  What is the least complex way to iterate a LinkedList in Java?
What is the least complex way to iterate a LinkedList in Java?

Time:11-09

I have the simple task to print elements inside a LinkedList that has no duplicates with commas in between, but I have come up with two ways to do it and I'm unsure about how LinkedList iteration works so I don't know which way is best. I have some assumptions about both ways.

    public static void main(String[] args) {
        LinkedList<Integer> pres = new LinkedList<Integer>();
        pres.add(112);
        pres.add(114);
        pres.add(326);
        pres.add(433);
        pres.add(119);
// ---------------------------------- METHOD 1 ---------------------------------
        for (int i = 0; i < pres.size(); i  ) {
            System.out.print(pres.get(i)   (i == pres.size() - 1 ? "" : ","));
        }

// ---------------------------------- METHOD 2 ---------------------------------
        for (int courseIndex : pres) {
            System.out.print(courseIndex   (courseIndex == pres.getLast() ? "" : ","));
        }
    }

For Method 1, I'm wondering if calling pres.get(i) in every iteration traverses the list from the beginning each time: (112) - (112 -> 114) - (112 -> 114 -> 326)... Or does the pointer stay where it last was and just move to the next element?

For Method 2, it seems like the foreach loop avoids the possible problem that I'm assuming in Method 1, but I'm calling getLast on every iteration as well. Is it a doubly linked list? Is get last an O(1) operation? If not, is calling getLast on each iteration even worse than Method 1, since it traverses the list all the way down each time?

CodePudding user response:

In a linked list, get-by-index (get(i)) is slow and can require iterating through much of the list if the index isn't near the ends. You ask if it just moves "the pointer", but there is no such pointer. Method 1 is therefore a bad idea.

Method 2 is the right idea. The for(var: list) will use an iterator, which is exactly the kind of pointer you are talking about.

Checking the last element is bad form, though, even though it is a double-linked list. You should do it something like this, instead of writing code that behaves oddly if the no-duplicates rule is broken:

String sep = "";
for (int courseIndex : pres) {
    System.out.print(sep   courseIndex);
    sep = ",";
}
System.out.println();

Actually, I/O calls should usually be considered slow, so it's best to make just one per line:

StringBuilder buf = new StringBuilder();
for (int courseIndex : pres) {
    if (buf.length() > 0) {
        buf.append(",");
    }
    buf.append(courseIndex);
}
System.out.println(buf.toString());

CodePudding user response:

String s = pres.stream()
    .map(Integer::toString)
    .collect(Collectors.joining(", "));

By the way:

    List<Integer> pres = new LinkedList<>();
    Collections.addAll(pres,
        112, 114, 326, 433, 119);

or

    List<Integer> pres = List.of(112, 114, 326, 433, 119);

You then later might change to an other implementation:

    List<Integer> pres = new ArrayList<>();
  • Related