Here's a class I wrote that implements Iterable<Integer> for an arithmetic series (from start to stop in steps of step)
package com.example.test;
import java.util.Iterator;
import com.google.common.collect.AbstractIterator;
public class ArithmeticSeries implements Iterable<Integer>
{
final private int start, step, stop;
public int getStart() { return this.start; }
public int getStep() { return this.step; }
public int getStop() { return this.stop; }
public ArithmeticSeries(int start, int step, int stop)
{
this.start = start;
this.step = step;
this.stop = stop;
}
#Override public Iterator<Integer> iterator()
{
return new AbstractIterator<Integer>() {
private Integer n = null;
#Override protected Integer computeNext() {
int next;
if (this.n == null)
{
next = getStart();
}
else
{
next = this.n + getStep();
if ((getStep() > 0 && next > getStop())
|| (getStep() < 0 && next < getStop()))
return endOfData();
}
this.n = next;
return next;
}
};
}
#Override public String toString() {
return getStart()+":"+getStep()+":"+getStop();
}
public static void main(String[] args) {
Iterable<Integer> range = new ArithmeticSeries(100,-1,80);
System.out.println(range);
for (int i : range)
System.out.println(i);
}
}
Is there a way to implement iterator() that's more elegant? I don't like the null check and use of Integer (alternative would be an extra flag boolean firstTime), it just seems wrong.
return new AbstractIterator<Integer>() {
int next = getStart();
#Override protected Integer computeNext() {
if (isBeyondEnd(next)) {
return endOfData();
}
Integer result = next;
next = next + getStep();
return result;
}
};
If you wanted to, you could probably implement this as an immutable List<Integer>. If you extend AbstractList then the Iterator would be taken care of for you. Actually, I think AbstractList would really be the best way to go. The whole class would look like something like this (I haven't checked that it works right in all situations):
public class ArithmeticSeries extends AbstractList<Integer> {
private final int start;
private final int step;
private final int size;
public ArithmeticSeries(int start, int end, int step) {
this.start = start;
this.step = (start < end) ? step : -step;
this.size = (end - start) / this.step + 1;
}
#Override public Integer get(int index) {
return start + step * index;
}
#Override public int size() {
return size;
}
}
You can use a Function to abstract the successive values and a Predicate to control the end of iteration, eventually creating an Unfold implementation:
public final class UnfoldIterator<E> implements Iterator<E> {
public static <E> Iterator<E> unfold(E initial, Function<? super E, ? extends E> next, Predicate<? super E> finished) {
return new UnfoldIterator<E>(initial, next, finished)
}
private final Function<? super E, ? extends E> next;
private final Predicate<? super E> finished;
private E element;
public UnfoldIterator(E initial, Function<? super E, ? extends E> next, Predicate<? super E> finished) {
super();
this.next = next;
this.finished = finished;
this.element = initial;
}
#Override protected Integer computeNext() {
if (finished.apply(element)) {
return endOfData();
}
E result = element;
element = next.apply(element);
return result;
}
}
Then ArithmeticSeries becomes:
public Iterable<Integer> series(final int start, final int step, final int stop) {
return new Iterable<Integer>() {
public Iterator<Integer> iterator() {
return new UnfoldIterator<Integer>(start, new Function<Integer, Integer>() {
public Integer apply(Integer from) {
return from - step;
}
}, new Predicate<Integer>() {
public boolean apply(Integer input) {
return input >= stop;
}
});
}
};
}
Of course the code seems more complex now, but with appropriate base functions for comparison and algebra the call becomes much clearer:
return unfold(start, subtractBy(step), not(lessThan(stop)));
I think the best tool for your problem in guava is the AbstractLinkedIterator. Implementation of your example would look like this:
final Iterator<Integer> series = new AbstractLinkedIterator<Integer>(100) {
#Override protected Integer computeNext(final Integer previous) {
return previous == 80 ? null : previous - 1;
}
};
while (series.hasNext()) {
System.out.println(series.next());
}
You can easily create an Iterable adapter for this iterator, e.g. like this:
package sk.the0retico.guava;
import java.util.Iterator;
import com.google.common.base.Function;
import com.google.common.collect.AbstractLinkedIterator;
public class LinkedIterable<T> implements Iterable<T> {
public static final <T> Iterable<T> from(final T first,
final Function<T, T> computeNext) {
return new LinkedIterable<T>(first, computeNext);
}
public static void main(final String[] args) {
final Iterable<Integer> series = LinkedIterable.from(100,
new Function<Integer, Integer>() {
#Override public Integer apply(final Integer input) {
return input == 80 ? null : input - 1;
}
});
for (final Integer value : series) {
System.out.println(value);
}
}
private final Function<T, T> computeNext;
private final T first;
public LinkedIterable(final T first, final Function<T, T> computeNext) {
this.first = first;
this.computeNext = computeNext;
}
#Override public Iterator<T> iterator() {
return new AbstractLinkedIterator<T>(first) {
#Override protected T computeNext(final T previous) {
return computeNext.apply(previous);
}
};
}
}
However this approach makes special constraints on the provided function returning null.
Related
My understanding is this ask of mine is NOT possible in a straight forward way. but I want to find a solution that works.
Here is how I get an Iterable for NamedNodeMap(javax package);
private static Iterable<Node> iterableNamedNodeMap(NamedNodeMap namedNodeMap) {
return () -> new Iterator<Node>() {
private int index = 0;
#Override
public boolean hasNext() {
return index < namedNodeMap.getLength();
}
#Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return namedNodeMap.item(index++);
}
};
}
And here is the iterable for NodeList(javax)
private static Iterable<Node> iterableNamedNodeMap(NodeList nodeList) {
return () -> new Iterator<Node>() {
private int index = 0;
#Override
public boolean hasNext() {
return index < nodeList.getLength();
}
#Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return nodeList.item(index++);
}
};
}
Since they are pretty much identical except for the parameters,
I was hoping for something like this, which of-course is not right. Both NodeList and NamedNodeMap does not implement a common interface. so what is the best way to do here.
private static <T extends NodeList | NamedNodeMap> Iterable<Node> iterableNamedNodeMap(T in) {
return () -> new Iterator<Node>() {
private int index = 0;
#Override
public boolean hasNext() {
return index < in.getLength();
}
#Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return in.item(index++);
}
};
You could reduce some of the boilerplate by creating a factory method that accepts two functional interfaces, taken from NodeList or NamedNodeMap using method references:
private static Iterable<Node> iterableNodes(
Supplier<int> lengthGetter,
Function<int, Node> itemGetter
) {
return () -> new Iterator<Node>() {
private int index = 0;
#Override
public boolean hasNext() {
return index < lengthGetter.get();
}
#Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return itemGetter.apply(index++);
}
};
}
private static Iterable<Node> iterableNamedNodeMap(NamedNodeMap namedNodeMap) {
return iterableNodes(namedNodeMap::getLength, namedNodeMap::item);
}
private static Iterable<Node> iterableNodeList(NodeList nodeList) {
return iterableNodes(nodeList::getLength, nodeList::item);
}
I wrote my own PriorityQueue class to manage unlimited elements. TO do this I declared an ArrayList and then I used the standard methods to add/swap the elements in it, but I get the error in the title. This is my code:
public class PriorityQueue<E extends Comparable<E>> {
private ArrayList<E> queue;
public PriorityQueue() {
queue= new ArrayList<>();
}
public <T> int size() {
return queue.size();
}
public <T> boolean isEmpty() {
return queue.isEmpty();
}
public <T> void insert(E element) {
queue.add(queue.size(), element);
siftUp(queue.size()-1);
}
public <T> void siftUp(int size) {
E elem = queue.get(size);
for (; size>0 && elem.compareTo(queue.get(size/2))==1; size=size/2)
queue.add(size, queue.get(size/2));
queue.add(size, elem);
}
}
How do I can solve it?
Edit: changed from "T elem" to "E elem" and now it compiles, but inserts two identical elements.
// perhaps this what you meant to do... Maybe? Kinda?
public class PriorityQueue<E> extends Comparable<E>
{
private ArrayList<E> queue = new ArrayList<E>();
public PriorityQueue() { }
public int size() { return queue.size(); }
public boolean isEmpty() { return queue.isEmpty(); }
public void insert(E element) {
queue.add(queue.size(), element);
siftUp(queue.size() - 1);
}
public void siftUp(int size) {
E elem = queue.get(size);
for (; size>0 && elem.compareTo(queue.get(size/2))==1; size=size/2)
queue.add(size, queue.get(size/2));
queue.add(size, elem);
}
}
I am trying to write a generic heap class.
import java.util.ArrayList;
public class heap<T extends Comparable<T>>
{
private ArrayList<T> h;
private int size;
public heap()
{
h = new ArrayList<T>();
h.add(null);
size = 0;
}
public T getMin()
{
return h.get(1);
}
public T popMin()
{
T tmp = getMin();
h.set(1, h.get(size));
size--;
sift(1);
return tmp;
}
public void insert(T key)
{
h.add(key);
percolate(++size);
}
public int getSize()
{
return this.size;
}
private int getLeftSon(int i)
{
return (i<<1<=size)? i<<1 : 0;
}
private int getRightSon(int i)
{
return ((i<<1)+1<=size)? (i<<1)+1 : 0;
}
private int getFather(int i)
{
return ((i>>1)!=0)? i>>1 : 0;
}
private void swap(int i, int j)
{
T tmp = h.get(i);
h.set(i, h.get(j));
h.set(j, tmp);
}
private void sift(int i)
{
int son;
do {
son = 0;
if (getLeftSon(i) != 0)
{
son = getLeftSon(i);
if (getRightSon(i) != 0 && h.get(getRightSon(i)).compareTo(h.get(getLeftSon(i))) > 0)
son = getRightSon(i);
if (h.get(son).compareTo(h.get(i)) <= 0)
son = 0;
}
if (son!=0) {
swap(i, son);
i = son;
}
} while (son!=0);
}
private void percolate(int i)
{
T key = h.get(i);
while ((i > 1) && (key.compareTo(h.get(getFather(i))) > 0))
{
h.set(i, h.get(getFather(i)));
i = getFather(i);
}
h.set(i, key);
}
}
All good. It works like a charm. Excepting one thing: if I work with Integers I don't have 'access' to the method compareTo from Integer. meaning that I can not override it's behaviour. I will always have a Max heap this way. Can Integer compareTo by override (I don't think it can)?
So what can I do apart from creating another class MyInteger extends Integer{...} and override it there.
You could make your heap accept a Comparator in constructor and then provide a Comparator that reverses the order.
That's what the Comparator is for actually - defining an ordering that's not a natural one for the given class, being able to define multiple orderings of the same class, or indeed defining an ordering for a class you cannot modify.
The approach of accepting a comparator at construction time can be seen in TreeSet for example.
Example code stub:
public class Heap<T> { /* no need for items to extend Comparable anymore */
private final Comparator<T> cmp;
public Heap(Comparator<T> cmp) {
this.cmp = cmp;
...
}
...
}
... and then use cmp.compare(item1, item2) wherever you now use item2.compareTo(item2).
I have basic understanding of how to apply Mockito framework.
But when it comes to some real time scenarios I failed to write tests in Isolation(by Mocking the dependent classes).
Can you help me to write Unit test for PriorityQueuePrinter class by Mocking PriorityQueue Implementation(BinaryMaxHeap.java).
I wrote testPriorityQueue() with BinaryMaxHeap object, in this case my test becomes success but I want to achieve the same to mock BinaryMaxHeap so that my test will be Isolate. I think I have to set method behaviours also in my test method.
In short, Priority Queue is the Implementation for BinaryHeapTree and Printer class uses Priority Queue.
Below are the code classes.
public interface PriorityQueue<T extends Comparable<T>> {
int size();
void insert(T element);
T popMax();
}
public class BinaryMaxHeap<T extends Comparable<T>> implements PriorityQueue<T> {
private ArrayList<T> items;
public BinaryMaxHeap() {
items = new ArrayList<T>();
}
public int size() {
return items.size();
}
public void insert(T element) {
items.add(element);
shiftUp();
}
public T popMax() {
if (items.size() == 1) {
return items.remove(0);
}
T hold = items.get(0);
items.set(0, items.remove(items.size()-1));
shiftDown();
return hold;
}
/*
* place newly added element in correct position in binary tree
*/
private void shiftUp() {
int k = items.size() - 1;
while (k > 0) {
int p = (k-1) / 2; // get parent element index
T child = items.get(k);
T parent = items.get(p);
if (child.compareTo(parent) > 0) {
// parent and child are not in correct position, need to swap
items.set(k, parent);
items.set(p, child);
k = p;
} else {
break;
}
}
}
private void shiftDown() {
int k = 0;
int l = 2*k+1; // left leaf node
while (l < items.size()) {
int max = l; // assume left node as max element
int r = l+1; // right leaf node
if (r < items.size()) {
if (items.get(r).compareTo(items.get(l)) > 0) {
max++; // identify max element in leaf nodes
}
}
T parent = items.get(k);
T child = items.get(max);
if (parent.compareTo(child) < 0) {
// parent element is less than leaf node, need to swap it
T temp = items.get(k);
items.set(k, items.get(max));
items.set(max, temp);
k = max;
l = 2*k+1;
} else {
break;
}
}
}
}
public interface Printer {
public <T extends Comparable<T>> String asSortedString(T... values);
}
public class PriorityQueuePrinter implements Printer {
private PriorityQueue priorityQueue = null;
public <T extends Comparable<T>> PriorityQueuePrinter(PriorityQueue<T> priorityQueue) {
this.priorityQueue = priorityQueue;
}
public <T extends Comparable<T>> String asSortedString(T... values) {
//PriorityQueue<T> priorityQueue =
addElements(values);
//return getSortedElements();
return null;
}
private <T extends Comparable<T>> void addElements(T... values) {
//PriorityQueue<T> priorityQueue = new BinaryMaxHeap<T>();
for (T element : values) {
priorityQueue.insert(element);
}
//return priorityQueue;
}
public int size() {
return priorityQueue.size();
}
private String getSortedElements() {
StringBuilder sortedElements = new StringBuilder();
boolean isFirstElement = true;
while(priorityQueue.size() > 0) {
if (!isFirstElement) {
sortedElements.append(",");
}
isFirstElement = false;
sortedElements.append(priorityQueue.popMax());
}
return sortedElements.toString();
}
public static void main(String a[]) {
PriorityQueuePrinter p = new PriorityQueuePrinter(new BinaryMaxHeap<Integer>());
String sortedElements = p.asSortedString(1,4,6,3,2);
System.out.println(sortedElements);
}
}
Below is the sample test code tried but not able to complete.
public class PrinterTest {
#Mock
PriorityQueue<Integer> mockPriorityQueue; // mock object
PriorityQueue<Integer> priorityQueue;
#Test
public void testPriorityQueueWithMock() {
PriorityQueuePrinter printer = new PriorityQueuePrinter(mockPriorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Ignore
public void testPriorityQueue() {
priorityQueue = new BinaryMaxHeap<Integer>();
PriorityQueuePrinter printer = new PriorityQueuePrinter(priorityQueue);
String s = printer.asSortedString(5,3,6);
assertEquals("6,5,3", s);
}
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#After
public void tearDown() throws Exception {
System.out.println("==tearDown==");
}
}
#Before
public void setUp() throws Exception {
//mockPriorityQueue = new BinaryMaxHeap<Integer>();
MockitoAnnotations.initMocks(this);
}
}
To be precise, I am trying to flatten a tree and I am stuck on trying to get the values of private attributes in a generic class using a generic function.
I have attached the classes to show how the tree is structured exactly. But it's looks something like this:
/|\
1 | 6
/|\
5 4 9
I am going to paste my attempt at the end. First, let me introduce the classes:
Triple simply stores three values of the same type.
public class Triple<V> {
private final V l, m, r;
public Triple(V l, V m, V r) {
this.l = l;
this.m = m;
this.r = r;
}
public V left() { return l; }
public V middle() { return m; }
public V right() { return r; }
}
Straightforward interface:
public interface Function<P, R> {
R apply(P p);
}
Now, for a tricky class. This one is simply a type that stores one of EitherOr of two types of value, but not both.
public class EitherOr<A,B> {
// Constructs a left-type EitherOr
public static <A> EitherOr left(A a) {
return new EitherOr(a, null);
}
// Constructs a right-type EitherOr
public static <B> EitherOr right(B b) {
return new EitherOr(null, b);
}
private final A a;
private final B b;
private EitherOr(A a, B b) {
this.a = a; this.b = b;
}
public<T> T ifLeft(Function<A,T> f) {
return f.apply(a);
}
public<T> T ifRight(Function<B,T> f) {
return f.apply(b);
}
public boolean isLeft() {
return b == null;
}
}
I know this is getting long, but bear with me. This class implements the tree structure.
public interface Tree<T> {
EitherOr<T, Triple<Tree<T>>> get();
static final class Leaf<T> implements Tree<T> {
public static <T> Leaf<T> leaf (T value) {
return new Leaf<T>(value);
}
private final T t;
public Leaf(T t) { this.t = t; }
#Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.left(t);
}
}
static final class Node<T> implements Tree<T> {
public static <T> Tree<T> tree (T left, T middle, T right) {
return new Node<T>(Leaf.leaf(left), Leaf.leaf(middle), Leaf.leaf(right));
}
private final Triple<Tree<T>> branches;
public Node(Tree<T> left, Tree<T> middle, Tree<T> right) {
this.branches = new Triple<Tree<T>>(left, middle, right);
}
#Override
public EitherOr<T, Triple<Tree<T>>> get() {
return EitherOr.right(branches);
}
}
}
Alright. Here is my idea for flattening:
public class MyFlattenTree<T> implements FlattenTree<T> {
public List<T> flattenInOrder(Tree<T> tree) {
List<T> list = new ArrayList<T>();
EitherOr<T, Triple<Tree<T>>> EitherOr;
EitherOr = tree.get();
// it is a leaf
if (EitherOr.isLeft()) {
// This is where the problem lies
// I don't how to get the value using a function f
list.add((T) EitherOr.ifLeft(f));
return list;
}
else {
// basically recursively go through the tree somehow
}
return null;
}
}
As I said, I am stuck with trying to retreive the value in the EitherOr class using the Function interface. I am thinking of implementing the Function interface and write a function for "apply" that just gets the value, but I am not sure how to do that. Any help would be appreciated. Thanks!
So, here is your flattenInOrder method:
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
Quite simple, assuming that:
ifLeftFunction yields a single element (since EitherOr<T, Triple<Tree<T>>> has a single T elem' if it s "left")
... and:
ifRightFunction yields a collection of elements (since EitherOr<T, Triple<Tree<T>>> has a list of T elems' if it is "right")
Let's look into these functions now:
ifLeftFunction is... basic. I want to extract a T from... a T.
final Function<T, T> ifLeftFunction = new Function<T, T>() {
#Override
public T apply(final T t) {
return t;
}
};
ifRightFunction is slightly more complex: it has to be recursive and collect all Ts from the Tree it's browsing:
final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
#Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
And... you're done!
Sample working code:
public class MyFlattenTree<T> {
private final Function<Triple<Tree<T>>, List<T>> ifRightFunction = new Function<Triple<Tree<T>>, List<T>>() {
#Override
public List<T> apply(final Triple<Tree<T>> t) {
final List<T> res = new ArrayList<>();
res.addAll(MyFlattenTree.this.flattenInOrder(t.left()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.middle()));
res.addAll(MyFlattenTree.this.flattenInOrder(t.right()));
return res;
}
};
private final Function<T, T> ifLeftFunction = new Function<T, T>() {
#Override
public T apply(final T t) {
return t;
}
};
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
public List<T> flattenInOrder(final Tree<T> tree) {
final EitherOr<T, Triple<Tree<T>>> EitherOr = tree.get();
if (EitherOr.isLeft()) {
return Collections.singletonList(EitherOr.ifLeft(this.ifLeftFunction));
}
return EitherOr.ifRight(this.ifRightFunction);
}
}
Note that I'm creating the exact Tree you're featuring as an example in your question in the main method here:
public static void main(final String[] args) {
final Tree<String> tree = new Node<>(new Leaf<>("1"), new Node<>(new Leaf<>("5"), new Leaf<>("4"), new Leaf<>("9")), new Leaf<>("6"));
System.out.println(new MyFlattenTree<String>().flattenInOrder(tree));
}
Output: [1, 5, 4, 9, 6]
Cheers ;)