To ensure that our collection can be iterated using iterator or for-each loop, we have to take care of following steps:
I have added a simple generic linked list implementation below that uses above entities to make the linked list iterable.
package org.algorithms.linkedlist; import java.util.Iterator; import java.util.NoSuchElementException; public class CustomLinkedList<T> implements Iterable<T> { Node<T> head, current; private static class Node<T> { T value; Node<T> next; Node(T value) { this.value = value; } } public CustomLinkedList(T value) { head = new Node<>(value); } public Iterator<T> iterator() { return new CustomLinkedListIterator(); } private class CustomLinkedListIterator implements Iterator<T> { Node<T> node = head; @Override public boolean hasNext() { return node != null; } @Override public T next() { if (!hasNext()) throw new NoSuchElementException(); Node<T> prevNode = node; node = node.next; return prevNode.value; } @Override public void remove() { throw new UnsupportedOperationException("Removal logic not implemented."); } } public void add(T value) { Node<T> current = head; while (current.next != null) current = current.next; current.next = new Node<>(value); } } class MyApp { public static void main(String[] args) { CustomLinkedList<String> myList = new CustomLinkedList<>("A"); myList.add("B"); myList.add("C"); myList.add("D"); // Test #1 System.out.println("Using Iterator:"); Iterator<String> iterator = myList.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.print(element + " "); } // Test #2 System.out.println("\n\nUsing for-each:"); for (String data : myList) { System.out.print(data + " "); } } }
Output
Using Iterator: A B C D Using for-each: A B C D
This will run in Java 7+. You can make it run on Java 5 and Java 6 also by substitutin
LinkedList<Integer> list = new LinkedList<>(1);
with
LinkedList<Integer> list = new LinkedList<Integer>(1);
or just any other version by incorporating the compatible changes.
Collections in Java only work for objects. I.e. there is no Map<int, int> in Java. Instead, primitive values need to be boxed into objects, as in Map<Integer, Integer>. Java auto-boxing will enable transparent use of these collections:
Map<Integer, Integer> map = new HashMap<>(); map.put(1, 17); // Automatic boxing of int to Integer objects int a = map.get(1); // Automatic unboxing.
Unfortunately, the overhead of this is substantial. A HashMap<Integer, Integer> will require about 72 bytes per entry (e.g. on 64-bit JVM with compressed pointers, and assuming integers larger than 256, and assuming 50% load of the map). Because the actual data is only 8 bytes, this yields a massive overhead. Furthermore, it requires two level of indirection (Map -> Entry -> Value) it is unnecessarily slow.
There exist several libraries with optimized collections for primitive data types (that require only ~16 bytes per entry at 50% load, i.e. 4x less memory, and one level of indirection less), that can yield substantial performance benefits when using large collections of primitive values in Java.
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions