Mit der For-Loop aus Java 5 über eigene Strukturen iterieren

Thomas Darimont

Erfahrenes Mitglied
Hallo!

Um die For-Loop aus Java 5 für eigene Strukturen verwenden zu können muss diese Struktur nur das Iterable Interface implementieren.

Beispiel:
Java:
package de.tutorials;

import java.util.Iterator;

public class IterableExample {
    public static void main(String[] args) {
        X x = new X();
        for(String s : x){
            System.out.println(s);
        }
    }
    
    static class X implements Iterable<String>{
        public Iterator<String> iterator() {
            return new Iterator<String>(){
                public boolean hasNext() {
                    return true;
                }

                public String next() {
                    return String.valueOf(System.nanoTime());
                }

                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }
    }
}

Etwas praxisnäher könnte man sich auch sowas darunter vorstellen:
Java:
package de.tutorials;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class IterableExample {
	public static void main(String[] args) {
		Order order = new Order("Tom").with(
				new Product("1", "Grüner Tee", 2, 2.50D)).with(
				new Product("2", "Gummibärchen", 1, 1.99D));
		
		for(Product product : order){
			System.out.println(product);
		}
	}

	static class Order implements Iterable<Product> {

		String customer;

		Set<Product> items = new HashSet<Product>();

		public Order(String customer) {
			super();
			this.customer = customer;
		}

		public Iterator<Product> iterator() {
			return this.items.iterator();
		}

		public Order with(Product orderItem) {
			this.items.add(orderItem);
			return this;
		}

		/**
		 * @return the items
		 */
		public Set<Product> getItems() {
			return items;
		}

		/**
		 * @param items
		 *            the items to set
		 */
		public void setItems(Set<Product> items) {
			this.items = items;
		}

	}

	static class Product {
		String id;

		String name;

		int quantity;

		double salesPrice;
		

		public Product(String id, String name, int quantity, double salesPrice) {
			super();
			this.id = id;
			this.name = name;
			this.quantity = quantity;
			this.salesPrice = salesPrice;
		}

		public Product() {
			super();
		}

		/**
		 * @return the id
		 */
		public String getId() {
			return id;
		}

		/**
		 * @param id
		 *            the id to set
		 */
		public void setId(String id) {
			this.id = id;
		}

		/**
		 * @return the name
		 */
		public String getName() {
			return name;
		}

		/**
		 * @param name
		 *            the name to set
		 */
		public void setName(String name) {
			this.name = name;
		}

		/**
		 * @return the quantity
		 */
		public int getQuantity() {
			return quantity;
		}

		/**
		 * @param quantity
		 *            the quantity to set
		 */
		public void setQuantity(int quantity) {
			this.quantity = quantity;
		}

		/**
		 * @return the salesPrice
		 */
		public double getSalesPrice() {
			return salesPrice;
		}

		/**
		 * @param salesPrice
		 *            the salesPrice to set
		 */
		public void setSalesPrice(double salesPrice) {
			this.salesPrice = salesPrice;
		}


		public String toString() {
			return this.id + " " + this.name + " " + this.quantity + " " + this.salesPrice;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int PRIME = 31;
			int result = 1;
			result = PRIME * result + ((id == null) ? 0 : id.hashCode());
			result = PRIME * result + ((name == null) ? 0 : name.hashCode());
			result = PRIME * result + quantity;
			long temp;
			temp = Double.doubleToLongBits(salesPrice);
			result = PRIME * result + (int) (temp ^ (temp >>> 32));
			return result;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final Product other = (Product) obj;
			if (id == null) {
				if (other.id != null)
					return false;
			} else if (!id.equals(other.id))
				return false;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			if (quantity != other.quantity)
				return false;
			if (Double.doubleToLongBits(salesPrice) != Double
					.doubleToLongBits(other.salesPrice))
				return false;
			return true;
		}

	}

}

Gruß Tom
 
Ich finde das komisch. Die for-Schleife ist (wahrscheinlich) als AST Transformation realisiert, die an der Stelle den Typ Iterable<T> sehen will. Genausogut könnte da aber ein Iterator<T> stehen. Das einzige, was sich an der Transformation ändert, ist, dass kein Aufruf an die "iterator()" Methode stattfindet, weil unnötig.

Ich hätte da wenigstens eine Methode in der Collections Klasse erwartet, die aus einem Iterator ein Iterable macht.
 
Hallo!

Ich hätte da wenigstens eine Methode in der Collections Klasse erwartet, die aus einem Iterator ein Iterable macht.
Ja sowas wäre nett gewesen... hmmm vielleicht gibts ja intern sowas... mal schauen.

Java:
/**
 * 
 */
package de.tutorials;

import java.util.Iterator;

/**
 * @author Thomas.Darimont
 *
 */
public class IterableIteratorExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        for(String s : new X()){
            System.out.println(s);
        }
    }
    
    static class X implements Iterable<String>{
        public Iterator<String> iterator() {
            return new IterableIterator<String>(){
                int count;
                public boolean hasNext() {
                    return count++ < 10;
                }

                public String next() {
                    return String.valueOf(System.nanoTime());
                }

                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }
        
    }
    
    static abstract class IterableIterator<T> implements Iterator<T>, Iterable<T>{
        public Iterator<T> iterator() {
            return this;
        }
    }
}

Gruß Tom
 
Zurück