Skip to content

Commit d659477

Browse files
committed
Write example programs and the main demo program
1 parent b5f0e87 commit d659477

File tree

5 files changed

+355
-0
lines changed

5 files changed

+355
-0
lines changed

examples/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id 'java'
3+
id 'application'
34
}
45

56
sourceCompatibility = 1.11
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package com.mayankrastogi.cs474.hw2.examples;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
9+
public class IteratorExamplesMain {
10+
11+
private static final Logger LOGGER = LoggerFactory.getLogger(IteratorExamplesMain.class);
12+
13+
public static void main(String[] args) {
14+
System.out.println("\n" +
15+
"=======================================================================================================\n" +
16+
" Design Pattern Verifier - Iterator Design Pattern Example Programs\n" +
17+
"=======================================================================================================\n" +
18+
"The iterator design pattern \"provides a way to access the elements of an aggregate object sequentially\n" +
19+
"without exposing its underlying representation.\n" +
20+
"\n" +
21+
"This application demonstrates 3 classes that use the iterator pattern and are annotated with different\n" +
22+
"variations of the @Iterator and @IterableAggregate (and their nested) annotations:\n" +
23+
"\n" +
24+
" 1. StudentCollection: A class annotated with @IterableAggregate that implements `java.lang.Iterable`.\n" +
25+
" It's iterator class is annotated with @Iterator and implements `java.util.Iterator`. The\n" +
26+
" iterator returns a `Student` object during iteration.\n" +
27+
" 2. RangeGenerator: A class annotated with @Iterator that generates a primitive `int` value on each\n" +
28+
" iteration within the range specified while constructing its object.\n" +
29+
" 3. Tree: A class annotated with @IterableAggregate that provides two methods annotated with\n" +
30+
" @IteratorFactory. The two methods return instances of `Tree.TreeIterator` that allow the user to\n" +
31+
" iterate the nodes of the tree in depth-first and breadth-first manners.\n" +
32+
"======================================================================================================="
33+
);
34+
35+
printExampleName("Student Collection Iteration Example");
36+
runStudentCollectionExample();
37+
38+
printExampleName("RangeGenerator Iteration Example");
39+
runRangeExample();
40+
41+
printExampleName("Tree Iteration Example");
42+
runTreeExample();
43+
}
44+
45+
private static void printExampleName(String exampleName) {
46+
System.out.println("\n\n" +
47+
"-------------------------------------------------------------------------------------------------------\n" +
48+
exampleName + "\n" +
49+
"-------------------------------------------------------------------------------------------------------\n" +
50+
"\n"
51+
);
52+
}
53+
54+
private static void runStudentCollectionExample() {
55+
LOGGER.debug("Creating StudentCollection...");
56+
var students = new StudentCollection();
57+
58+
students.addStudent(new Student("Alex", 20, Degree.Bachelors, 3.2f));
59+
students.addStudent(new Student("Bob", 25, Degree.Masters, 3.6f));
60+
students.addStudent(new Student("Chuck", 28, Degree.PhD, 3.5f));
61+
62+
LOGGER.debug("Iterating StudentCollection...");
63+
for (var student : students) {
64+
System.out.println("Name: " + student.getName());
65+
System.out.println("Age: " + student.getAge());
66+
System.out.println("Degree: " + student.getDegree());
67+
System.out.println("GPA: " + student.getGPA());
68+
System.out.println();
69+
}
70+
LOGGER.debug("StudentCollection Iteration Example Finished.");
71+
}
72+
73+
private static void runRangeExample() {
74+
int from = 1;
75+
int to = 10;
76+
77+
LOGGER.debug(String.format("Creating a RangeGenerator(from: %s, to: %s)...", from, to));
78+
var range = new RangeGenerator(from, to);
79+
80+
LOGGER.debug("Iterating RangeGenerator...");
81+
while (!range.isDone()) {
82+
System.out.println(range.next());
83+
}
84+
85+
LOGGER.debug("RangeGenerator Iteration Example Finished.");
86+
}
87+
88+
private static void runTreeExample() {
89+
System.out.println("" +
90+
"Sample Tree:\n" +
91+
"-----------\n" +
92+
"\n" +
93+
" 1\n" +
94+
" _______________________________|_______________________________\n" +
95+
" | | |\n" +
96+
" 2 3 4\n" +
97+
" _______|_______ _______|_______ _______|_______\n" +
98+
" | | | | | |\n" +
99+
" 5 6 7 8 9 10\n" +
100+
"\n");
101+
102+
LOGGER.debug("Creating 10 nodes using the RangeGenerator...");
103+
var allNodes = new ArrayList<Node<Integer>>();
104+
var range = new RangeGenerator(1, 10);
105+
while (!range.isDone()) {
106+
allNodes.add(new Node<>(range.next()));
107+
}
108+
LOGGER.debug("allNodes: " + allNodes);
109+
110+
LOGGER.debug("Creating Sample Tree...");
111+
112+
allNodes.get(0).children = Arrays.asList(allNodes.get(1), allNodes.get(2), allNodes.get(3));
113+
allNodes.get(1).children = Arrays.asList(allNodes.get(4), allNodes.get(5));
114+
allNodes.get(2).children = Arrays.asList(allNodes.get(6), allNodes.get(7));
115+
allNodes.get(3).children = Arrays.asList(allNodes.get(8), allNodes.get(9));
116+
117+
var tree = new Tree<>(allNodes.get(0));
118+
LOGGER.debug("tree: " + tree);
119+
120+
LOGGER.debug("Iterating tree using `dfsIterator()`...");
121+
122+
System.out.println("Depth-first tree traversal:");
123+
var iterator = tree.dfsIterator();
124+
while (!iterator.isDone()) {
125+
System.out.print(" " + iterator.next().data);
126+
}
127+
System.out.println();
128+
129+
LOGGER.debug("Iterating tree using `bfsIterator()`...");
130+
131+
System.out.println("Breadth-first tree traversal:");
132+
iterator = tree.bfsIterator();
133+
while (!iterator.isDone()) {
134+
System.out.print(" " + iterator.next().data);
135+
}
136+
System.out.println();
137+
138+
LOGGER.debug("Tree Iteration Example Finished.");
139+
}
140+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.mayankrastogi.cs474.hw2.examples;
2+
3+
import com.mayankrastogi.cs474.hw2.annotations.Iterator;
4+
5+
@Iterator(int.class)
6+
public class RangeGenerator {
7+
private final int maxValue;
8+
9+
private int currentValue;
10+
11+
public RangeGenerator(int from, int to) {
12+
this.maxValue = to;
13+
this.currentValue = from - 1;
14+
}
15+
16+
@Iterator.CurrentItem
17+
public int currentValue() {
18+
return currentValue;
19+
}
20+
21+
@Iterator.IsDone
22+
public boolean isDone() {
23+
return currentValue == maxValue;
24+
}
25+
26+
@Iterator.NextItem
27+
public int next() {
28+
return ++currentValue;
29+
}
30+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.mayankrastogi.cs474.hw2.examples;
2+
3+
import com.mayankrastogi.cs474.hw2.annotations.IterableAggregate;
4+
import com.mayankrastogi.cs474.hw2.annotations.Iterator;
5+
6+
import java.util.ArrayList;
7+
import java.util.NoSuchElementException;
8+
9+
enum Degree {
10+
Bachelors,
11+
Masters,
12+
PhD
13+
}
14+
15+
@IterableAggregate(StudentCollection.StudentCollectionIterator.class)
16+
public class StudentCollection implements Iterable<Student> {
17+
18+
private ArrayList<Student> studentsList = new ArrayList<>();
19+
20+
public void addStudent(Student student) {
21+
studentsList.add(student);
22+
}
23+
24+
public void removeStudent(Student student) {
25+
studentsList.remove(student);
26+
}
27+
28+
@Override
29+
@IterableAggregate.IteratorFactory
30+
public java.util.Iterator<Student> iterator() {
31+
return new StudentCollectionIterator();
32+
}
33+
34+
@Iterator(Student.class)
35+
public class StudentCollectionIterator implements java.util.Iterator<Student> {
36+
37+
private int currentIndex;
38+
39+
private StudentCollectionIterator() {
40+
currentIndex = -1;
41+
}
42+
43+
@Iterator.CurrentItem
44+
public Student current() {
45+
return currentIndex < 0 ? null : studentsList.get(currentIndex);
46+
}
47+
48+
@Override
49+
@Iterator.IsDone
50+
public boolean hasNext() {
51+
return currentIndex < studentsList.size() - 1;
52+
}
53+
54+
@Override
55+
@Iterator.NextItem
56+
public Student next() {
57+
if (hasNext()) {
58+
currentIndex++;
59+
return current();
60+
} else {
61+
throw new NoSuchElementException("StudentCollectionIterator has finished iterating over all the students in the collection");
62+
}
63+
}
64+
}
65+
}
66+
67+
class Student {
68+
69+
private String name;
70+
private int age;
71+
private Degree degree;
72+
private float gpa;
73+
74+
public Student(String name, int age, Degree degree, float gpa) {
75+
this.name = name;
76+
this.age = age;
77+
this.degree = degree;
78+
this.gpa = gpa;
79+
}
80+
81+
public String getName() {
82+
return name;
83+
}
84+
85+
public int getAge() {
86+
return age;
87+
}
88+
89+
public Degree getDegree() {
90+
return degree;
91+
}
92+
93+
public float getGPA() {
94+
return gpa;
95+
}
96+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.mayankrastogi.cs474.hw2.examples;
2+
3+
import com.mayankrastogi.cs474.hw2.annotations.IterableAggregate;
4+
import com.mayankrastogi.cs474.hw2.annotations.Iterator;
5+
6+
import java.util.ArrayDeque;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.NoSuchElementException;
10+
11+
@IterableAggregate(Tree.TreeIterator.class)
12+
public class Tree<T> {
13+
14+
private Node<T> root;
15+
16+
public Tree(Node<T> root) {
17+
this.root = root;
18+
}
19+
20+
@IterableAggregate.IteratorFactory
21+
public TreeIterator dfsIterator() {
22+
return new TreeIterator(true);
23+
}
24+
25+
@IterableAggregate.IteratorFactory
26+
public TreeIterator bfsIterator() {
27+
return new TreeIterator(false);
28+
}
29+
30+
@Override
31+
public String toString() {
32+
return "Tree(root: " + root + ")";
33+
}
34+
35+
@Iterator(Node.class)
36+
public class TreeIterator {
37+
private boolean dfs;
38+
private Node<T> currentNode;
39+
private ArrayDeque<Node<T>> deque;
40+
41+
private TreeIterator(boolean dfs) {
42+
this.dfs = dfs;
43+
deque = new ArrayDeque<>();
44+
deque.add(root);
45+
}
46+
47+
@Iterator.CurrentItem
48+
public Node<T> currentNode() {
49+
return currentNode;
50+
}
51+
52+
@Iterator.IsDone
53+
public boolean isDone() {
54+
return deque.isEmpty();
55+
}
56+
57+
@Iterator.NextItem
58+
public Node<T> next() {
59+
if (isDone()) throw new NoSuchElementException("All nodes in the tree have been traversed.");
60+
61+
currentNode = deque.pop();
62+
if (dfs) {
63+
var childrenIterator = currentNode.children.listIterator(currentNode.children.size());
64+
while (childrenIterator.hasPrevious()) {
65+
deque.push(childrenIterator.previous());
66+
}
67+
} else {
68+
deque.addAll(currentNode.children);
69+
}
70+
return currentNode();
71+
}
72+
}
73+
}
74+
75+
class Node<T> {
76+
T data;
77+
List<Node<T>> children;
78+
79+
public Node(T data) {
80+
this.data = data;
81+
this.children = new ArrayList<>();
82+
}
83+
84+
@Override
85+
public String toString() {
86+
return "Node(data: " + data + ", children: " + children + ")";
87+
}
88+
}

0 commit comments

Comments
 (0)