Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yield Return In Java

I've created a linked list in java using generics, and now I want to be able to iterate over all the elements in the list. In C# I would use yield return inside the linked list while going over the list of elements contained in the list.

How would I go about creating a java version of the above where I can iterate over all the items contained in the linked list?

I'm looking to be able to write code ala

LinkedList<something> authors = new LinkedList<something>(); for (Iterator<something> i = authors.Values ; i.HasNext())       doSomethingWith(i.Value); 

And was thinking that the Value 'property'/method would consist of code resembling

LinkedListObject<something> current = first; While (current != null){  yield return current.getValue();  current = current.getNext() } 

Edit: Notice that I'm not interested in using any 3rd party APIs. Built-in java functionality only.

like image 801
Kasper Holdum Avatar asked Feb 28 '10 19:02

Kasper Holdum


People also ask

Does Java have yield return?

The only issue is that you involve a thread synchronization which is a bit more hard to code, and has its performance penalties. So, yes, yield return is great and is missing from Java.

What is a yield in Java?

A yield() method is a static method of Thread class and it can stop the currently executing thread and will give a chance to other waiting threads of the same priority. If in case there are no waiting threads or if all the waiting threads have low priority then the same thread will continue its execution.

What yield return does?

Yield is the amount an investment earns during a time period, usually reflected as a percentage. Return is how much an investment earns or loses over time, reflected as the difference in the holding's dollar value.

How do you use yield return?

To use "yield return", you just need to create a method with a return type that is an IEnumerable (arrays and collections in. Net implements IEnumerable interface) with a loop and use "yield return" to return a value to set in the loop body.


2 Answers

You can return an anonymous implementation of Iterable. The effects are pretty pretty similar, just that this is a lot more verbose.

public Iterable<String> getStuff() {     return new Iterable<String>() {          @Override         public Iterator<String> iterator() {             return new Iterator<String>() {                  @Override                 public boolean hasNext() {                     // TODO code to check next                 }                  @Override                 public String next() {                     // TODO code to go to next                 }                  @Override                 public void remove() {                     // TODO code to remove item or throw exception                 }              };         }     }; } 
like image 85
voidvector Avatar answered Oct 02 '22 10:10

voidvector


"yield return" is a very sophisticated compiler trick. It basically lets you declaratively implement IEnumerable without any of the annoying details of "figuring out" how to build your iterator. The unfortunate thing is that it does not translate into other languages well because very few compilers have such a capability. In some ways "yield return" is as damning as revolutionary.

Basically in C#, the compiler will generate two implementations of IEnumerable and IEnumerator (of T). It does this by basically realizing your "method"'s local variables as instance fields in generated implementation classes as well as examining the frames containing a "yield return" artifact. Once you know this, it should be possible for a well rounded developer to accomplish the same thing explicitly... although not as concisely. To demonstrate, I will CONCAT!

public static <T> Iterable<T> concat(Iterable<T> x, Iterable<T> y) {     for(T e: x)     {         yield return e;     }      for(T e: y)     {         yield return e;     } }  // becomes ....  public static <E> Iterator<E> concat_(Iterable<E> x, Iterator<E> y) {     T e1, e2;     Iterator<E> i1, i2;      Iterator<E> s;     Iterator<E> s4 = new Iterator<E>()     {         public bool hasNext()         {             return false;         }          public E next()         {             throw ... ;         }          public void remove()         {             throw ... ;         }     }      Iterator<E> s3 = new Iterator<E>()     {         Iterator<E> act()         {             if(i2.hasNext())             {                 return i2;             }              i2 = y.iterator();             return (s = s4);         }          public bool hasNext()         {             return act().hasNext();         }          public E next()         {             return act().next();         }          public void remove()         {             return i2.remove();         }     }      Iterator<E> s2 = new Iterator<E>()     {         Iterator<E> act()         {             if(i1.hasNext())             {                 return i1;             }              i2 = y.iterator();             return (s = s3);         }          public bool hasNext()         {             return act().hasNext();         }          public E next()         {             return act().next();         }          public void remove()         {             return i1.remove();         }     };      Iterator<E> s1 = new Iterator<E>()     {         Iterator<E> act()         {             i1 = x.iterator();             return s = s2;         }          public bool hasNext()         {             return act().hasNext();         }          public E next()         {             return act().next();         }          public void remove()         {             return act().remove();         }     };      s = s1;     return new Iterator<T>()     {         public bool hasNext()         {             return s.hasNext();         }          public E next()         {             return s.next();         }          public void remove()         {             return s.remove();         }     }; }  public static <T> Iterable<T> concat(Iterable<T> x, Iterable<T> y) {     return new Iterable<T>()     {         public Iterator<T> iterator()         {             return concat_(x, y)         }     }; }  // tada! 

If you all will pardon my 3AM pseudo java...

like image 29
Garth Pickell Avatar answered Oct 02 '22 11:10

Garth Pickell