title: Refactoring a complex while loop into Java 8 stream
body: <p>I have a complex entity structure. Which contains the ID of the previous item ("previodElementId")</p>
  
  <pre><code>interface IPreviousElementEntity&lt;PK&gt; {
      public void setId(PK id);
      public PK getId();
      public void setPreviousElementId(PK previousElementId);
      public PK getPreviousElementId();
  }
  </code></pre>
  
  <p>After receiving all entities from DB, I need to convert the resulting list into a linked list, and the linked list should be organized by the previous id. </p>
  
  <p>I wrote the following code for conversion:</p>
  
  <pre><code>static &lt;T extends IPreviousElementEntity&gt; LinkedList&lt;T&gt; getLinkedListByPreviousId(Collection&lt;T&gt; collection) {
      LinkedList&lt;T&gt; linkedList = new LinkedList&lt;&gt;();
      if (collection == null || collection.isEmpty())
          return linkedList;
  
      // first find root element
      collection.stream()
              .filter(element -&gt; element.getPreviousElementId() == null)
              .forEach(linkedList::add);
  
      if (linkedList.isEmpty()) return linkedList;
  
      // TODO: convert to use stream. Please help!
      Boolean isRun = true;
      while (isRun) {
          for (T element : collection) {
              isRun = false;
              if (linkedList.getLast().getId().equals(element.getPreviousElementId())) {
                  linkedList.add(element);
                  isRun = true;
                  break;
              }
          }
      }
  
      return linkedList;
  }
  </code></pre>
  
  <p>But this code is terrible! Is it possible to write all these transformations on a stream? I especially want to get rid of the thundering while loop.</p>
  
  <p>My full code:</p>
  
  <pre><code>import java.util.*;
  
  public class App {
      public static void main(String[] args) {
          Entity entity1 = new Entity(3L, 2L, "third");
          Entity entity2 = new Entity(2L, 1L, "second");
          Entity entity3 = new Entity(4L, 3L, "forth");
          Entity entity4 = new Entity(1L, null, "first");
  
          List&lt;Entity&gt; entities = new ArrayList&lt;&gt;();
          entities.add(entity1);
          entities.add(entity2);
          entities.add(entity3);
          entities.add(entity4);
  
          LinkedList&lt;Entity&gt; linkedListByPreviousId = getLinkedListByPreviousId(entities);
          System.out.println(linkedListByPreviousId);
      }
  
      private static &lt;T extends IPreviousElementEntity&gt; LinkedList&lt;T&gt; getLinkedListByPreviousId(Collection&lt;T&gt; collection) {
          LinkedList&lt;T&gt; linkedList = new LinkedList&lt;&gt;();
          if (collection == null || collection.isEmpty())
              return linkedList;
  
          // first find root element
          collection.stream()
                  .filter(element -&gt; element.getPreviousElementId() == null)
                  .forEach(linkedList::add);
  
          if (linkedList.isEmpty()) return linkedList;
  
          //TODO: convert to use stream. Please help!
          Boolean isRun = true;
          while (isRun) {
              for (T element : collection) {
                  isRun = false;
                  if (linkedList.getLast().getId().equals(element.getPreviousElementId())) {
                      linkedList.add(element);
                      isRun = true;
                      break;
                  }
              }
          }
  
          return linkedList;
      }
  }
  
  interface IPreviousElementEntity&lt;PK&gt; {
      public void setId(PK id);
      public PK getId();
      public void setPreviousElementId(PK previousElementId);
      public PK getPreviousElementId();
  }
  
  class Entity implements IPreviousElementEntity&lt;Long&gt; {
      private Long id;
      private Long previousElementId;
      private String name;
  
      public Entity(Long id, Long previousElementId, String name) {
          this.id = id;
          this.previousElementId = previousElementId;
          this.name = name;
      }
  
      @Override
      public Long getId() {
          return id;
      }
  
      @Override
      public void setId(Long id) {
          this.id = id;
      }
  
      @Override
      public Long getPreviousElementId() {
          return previousElementId;
      }
  
      @Override
      public void setPreviousElementId(Long previousElementId) {
          this.previousElementId = previousElementId;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          Entity entity = (Entity) o;
          return Objects.equals(id, entity.id) &amp;&amp;
                  Objects.equals(previousElementId, entity.previousElementId) &amp;&amp;
                  Objects.equals(name, entity.name);
      }
  
      @Override
      public int hashCode() {
          return Objects.hash(id, previousElementId, name);
      }
  
      @Override
      public String toString() {
          final StringBuilder sb = new StringBuilder("Entity{");
          sb.append("id=").append(id);
          sb.append(", previousElementId=").append(previousElementId);
          sb.append(", name='").append(name).append('\'');
          sb.append('}');
          return sb.toString();
      }
  }
  </code></pre>