Skip to main content

Split your Loop

Greetings!

It is common thing in programming that we need to iterate over items. Question is, how do you iterate over collection and implement your logics? Most of the time, people violate single responsibility principle as loops are having multiple logics.
I would like to have cleaner separation between unrelated logics. If you pay attention, you can see that in loops, we are doing multiple things. Let's see a little (dirty) example.
public class SplitLoop {

  public static void main(String[] args) {
    List<Subject> subjects = Arrays.asList(new Subject("Maths", 90), new Subject("History", 85));

    int total = 0;
    int marksForMaths = 0;

    for (Subject subject : subjects) {
      total += subject.getMarks();
      if ("Maths".equals(subject.getTitle())) {
        marksForMaths = subject.getMarks();
      }
    }

    System.out.println("Total " + total + " for Maths " + marksForMaths);
  }

  static class Subject {
    private String title;
    private int marks;

    Subject(String title, int marks)
    {
      this.title = title;
      this.marks = marks;
    }
  }
}
Here, I want to calculate total score and marks for maths. However, those are two different things which I would like to separate. The refactoring technique I use is called Split Loop (splitLoop).
In this technique we do only one thing in a loop. In this example we will have two loops. One to get the total, another to get the marks for maths.
int total = 0;
for (Subject subject : subjects) {
  total += subject.getMarks();
}

int marksForMaths = 0;
for (Subject subject : subjects) {
  if ("Maths".equals(subject.getTitle())) {
	marksForMaths = subject.getMarks();
  }
}
Now the good thing is, I can improve this further with pipeline which was not possible before.
int total = subjects.stream().mapToInt(Subject::getMarks).sum();

int marksForMaths = subjects.stream()
      .filter(subject -> "Maths".equals(subject.getTitle()))
      .findAny()
      .map(Subject::getMarks)
      .orElse(0);
It is now a matter of adding another line for new requirement.

Perfomance

The main concern people raise in this kind of refactorings is performance. These simple things have no impact on performace even when the number of items are high. So do not afraid about the performace.

Happy refactoring ☺