Tree traversal in Java with Generic classes - java

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 ;)

Related

Unchecked generic in abstract inheritance (java)

I'm getting a compilation warning: "ExampleConsumer.java uses unchecked or unsafe operations." on line return example.distance(other);. How do I properly check the type? Obviously I need to enforce that the types are the same.
Here's my code:
Example.java
public abstract class Example<T, U> {
public T t;
public U u;
public Example(T t, U u) {
this.t = t;
this.u = u;
}
abstract double distance(Example<T, U> other);
}
SpecialExample.java
public class SpecialExample extends Example<Integer, Double> {
public SpecialExample(Integer i, Double d) {
super(i, d);
}
#Override
double distance(Example<Integer, Double> other) {
return (double)(t - other.t) + u * other.u;
}
}
BadExample.java
public class BadExample extends Example<String, String> {
public BadExample(String s1, String s2) {
super(s1, s2);
}
#Override
double distance(Example<String, String> other) {
return (double)(t.length() + other.t.length()) + (u.length() * other.u.length());
}
}
ExampleConsumer.java
public class ExampleConsumer<E extends Example> {
private E example;
public ExampleConsumer(E example) {
this.example = example;
}
public double combine(E other) {
return example.distance(other);
}
}
Main.java
class Main {
public static void main(String[] args) {
SpecialExample special = new SpecialExample(1, 2.0);
ExampleConsumer<SpecialExample> consumer = new ExampleConsumer<>(special);
BadExample bad = new BadExample("foo", "bar");
consumer.combine(special); // compiles with warning
// consumer.combine(bad); // doesn't compile = good!
}
}
Here's one solution:
ExampleConsumer.java
public class ExampleConsumer<A, B, E extends Example<A, B>> {
private E example;
public ExampleConsumer(E example) {
this.example = example;
}
public double combine(E other) {
return example.distance(other);
}
}
Main.java
class Main {
public static void main(String[] args) {
// ...
ExampleConsumer<Integer, Double, SpecialExample> consumer = new ExampleConsumer<>(special);
// ...
}
}
But I'd rather not have to repeat the Double/Integer types in Main.java :/

no suitable method found for add(int,T) with Generics

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);
}
}

In java, can you use the builder pattern with required and reassignable fields?

This is related to the following question:
How to improve the builder pattern?
I'm curious whether it's possible to implement a builder with the following properties:
Some or all parameters are required
No method receives many parameters (i.e., no list of defaults supplied to the initial builder factory method)
All builder fields can be reassigned an arbitrary number of times
The compiler should check that all parameters have been set
It is ok to require that parameters are initially set in some order, but once any parameter is set, all following builders can have this parameter set again (i.e., you can reassign the value of any field of the builder you wish)
No duplicate code should exist for setters (e.g., no overriding setter methods in builder subtypes)
One failed attempt is below (empty private constructors omitted). Consider the following toy builder implementation, and note that line with "Foo f2" has a compiler error because the inherited setter for a returns a BuilderB, not a BuilderFinal. Is there a way to use the java type system to parameterize the return types of the setters to achieve the above goals, or achieve them some other way.
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA newBuilder() {
return new BuilderC();
}
public static class BuilderA {
private volatile int a;
public BuilderB a(int v) {
a = v;
return (BuilderB) this;
}
public int a() {
return a;
}
}
public static class BuilderB extends BuilderA {
private volatile int b;
public BuilderC b(int v) {
b = v;
return (BuilderC) this;
}
public int b() {
return b;
}
}
public static class BuilderC extends BuilderB {
private volatile int c;
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}
Your requirements are really hard, but see if this generic solution fits the bill:
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA<? extends BuilderB<?>> newBuilder() {
return new BuilderFinal();
}
public static class BuilderA<T extends BuilderB<?>> {
private volatile int a;
#SuppressWarnings("unchecked")
public T a(int v) {
a = v;
return (T) this;
}
public int a() {
return a;
}
}
public static class BuilderB<T extends BuilderC<?>> extends BuilderA<T> {
private volatile int b;
#SuppressWarnings("unchecked")
public T b(int v) {
b = v;
return (T) this;
}
public int b() {
return b;
}
}
public static class BuilderC<T extends BuilderFinal> extends BuilderB<T> {
private volatile int c;
#SuppressWarnings("unchecked")
public T c(int v) {
c = v;
return (T) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC<BuilderFinal> {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}
To my knowledge the builder pattern should be used in case multiple parameters are used that make the invocation rather complicated as parameters might swap positions or not make it obviously clear what which parameter is for.
A rule of thumb would be to require compulsory parameters within the constructor of the builder and optional parameters within the methods. However, often more than 4 parameters may be required which makes the invocation again rather unclear and the pattern redundant. So a split up into default constructor and parameter setting for each parameter can also be used.
The checks should happen in a own method which is invoked within the build-method so you could invoke it using super. Compile-time security is only guaranteed on the correct data types (only exception - null is possible to, this has to be fetched within the checkParameters()-method). You can however force that all required parameters are set on requiring them within the Builder constructor - but as mentioned before, this may lead to a redundant pattern.
import java.util.ArrayList;
import java.util.List;
public class C
{
public static class Builder<T extends C, B extends C.Builder<? extends C,? extends B>> extends AbstractBuilder<C>
{
protected String comp1;
protected String comp2;
protected int comp3;
protected int comp4;
protected int comp5;
protected List<Object> comp6 = new ArrayList<>();
protected String optional1;
protected List<Object> optional2 = new ArrayList<>();
public Builder()
{
}
public B withComp1(String comp1)
{
this.comp1 = comp1;
return (B)this;
}
public B withComp2(String comp2)
{
this.comp2 = comp2;
return (B)this;
}
public B withComp3(int comp3)
{
this.comp3 = comp3;
return (B)this;
}
public B withComp4(int comp4)
{
this.comp4 = comp4;
return (B)this;
}
public B withComp5(int comp5)
{
this.comp5 = comp5;
return (B)this;
}
public B withComp6(Object comp6)
{
this.comp6.add(comp6);
return (B)this;
}
public B withOptional1(String optional1)
{
this.optional1 = optional1;
return (B)this;
}
public B withOptional2(Object optional2)
{
this.optional2.add(optional2);
return (B)this;
}
#Override
protected void checkParameters() throws BuildException
{
if (this.comp1 == null)
throw new BuildException("Comp1 violates the rules");
if (this.comp2 == null)
throw new BuildException("Comp2 violates the rules");
if (this.comp3 == 0)
throw new BuildException("Comp3 violates the rules");
if (this.comp4 == 0)
throw new BuildException("Comp4 violates the rules");
if (this.comp5 == 0)
throw new BuildException("Comp5 violates the rules");
if (this.comp6 == null)
throw new BuildException("Comp6 violates the rules");
}
#Override
public T build() throws BuildException
{
this.checkParameters();
C c = new C(this.comp1, this.comp2,this.comp3, this.comp4, this.comp5, this.comp6);
c.setOptional1(this.optional1);
c.setOptional2(this.optional2);
return (T)c;
}
}
private final String comp1;
private final String comp2;
private final int comp3;
private final int comp4;
private final int comp5;
private final List<?> comp6;
private String optional1;
private List<?> optional2;
protected C(String comp1, String comp2, int comp3, int comp4, int comp5, List<?> comp6)
{
this.comp1 = comp1;
this.comp2 = comp2;
this.comp3 = comp3;
this.comp4 = comp4;
this.comp5 = comp5;
this.comp6 = comp6;
}
public void setOptional1(String optional1)
{
this.optional1 = optional1;
}
public void setOptional2(List<?> optional2)
{
this.optional2 = optional2;
}
// further methods omitted
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(this.comp1);
sb.append(", ");
sb.append(this.comp2);
sb.append(", ");
sb.append(this.comp3);
sb.append(", ");
sb.append(this.comp4);
sb.append(", ");
sb.append(this.comp5);
sb.append(", ");
sb.append(this.comp6);
return sb.toString();
}
}
On extending D from C and also the builder, you need to override the checkParameters() and build() method. Due to the use of Generics the correct type will be return on invoking build()
import java.util.List;
public class D extends C
{
public static class Builder<T extends D, B extends D.Builder<? extends D, ? extends B>> extends C.Builder<D, Builder<D, B>>
{
protected String comp7;
public Builder()
{
}
public B withComp7(String comp7)
{
this.comp7 = comp7;
return (B)this;
}
#Override
public void checkParameters() throws BuildException
{
super.checkParameters();
if (comp7 == null)
throw new BuildException("Comp7 violates the rules");
}
#Override
public T build() throws BuildException
{
this.checkParameters();
D d = new D(this.comp1, this.comp2, this.comp3, this.comp4, this.comp5, this.comp6, this.comp7);
if (this.optional1 != null)
d.setOptional1(optional1);
if (this.optional2 != null)
d.setOptional2(optional2);
return (T)d;
}
}
protected String comp7;
protected D(String comp1, String comp2, int comp3, int comp4, int comp5, List<?> comp6, String comp7)
{
super(comp1, comp2, comp3, comp4, comp5, comp6);
this.comp7 = comp7;
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(super.toString());
sb.append(", ");
sb.append(this.comp7);
return sb.toString();
}
}
The abstract builder class is quite simple:
public abstract class AbstractBuilder<T>
{
protected abstract void checkParameters() throws BuildException;
public abstract <T> T build() throws BuildException;
}
The exception is simple too:
public class BuildException extends Exception
{
public BuildException(String msg)
{
super(msg);
}
}
And last but not least the main method:
public static void main(String ... args)
{
try
{
C c = new C.Builder<>().withComp1("a1").withComp2("a2").withComp3(1)
.withComp4(4).withComp5(5).withComp6("lala").build();
System.out.println("c: " + c);
D d = new D.Builder<>().withComp1("d1").withComp2("d2").withComp3(3)
.withComp4(4).withComp5(5).withComp6("lala").withComp7("d7").build();
System.out.println("d: " + d);
C c2 = new C.Builder<>().withComp1("a1").withComp3(1)
.withComp4(4).withComp5(5).withComp6("lala").build();
System.out.println(c2);
}
catch (Exception e)
{
e.printStackTrace();
}
}
Output:
c: a1, a2, 1, 4, 5, [lala]
d: d1, d2, 3, 4, 5, [lala], d7
Builders.BuildException: Comp2 violates the rules
... // StackTrace omitted
Though, before messing to much with Generics I'd suggest to stick to the KISS policy and forget inheritance for builders and code them simple and stupid (with part of them including dumb copy&paste)
#edit: OK, after all the work done and re-reading the OP as well as the linked post I had a totally wrong assumption of the requirements - like a German wording says: "Operation successful, patient is dead" - though I leave this post here in case someone wants a copy&paste like solution for a builder-inheritance which actually returns the correct type instead of the the base type
I had a crazy idea once, and it kind of goes against some of your requirements, but I think you can have the builder constructor take the required parameters, but in a way that makes it still clear which parameters are being set. Take a look:
package myapp;
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static class Builder {
private int a;
private int b;
private int c;
public Builder(A a, B b, C c) {
this.a = a.v;
this.b = b.v;
this.c = c.v;
}
public Builder a(int v) { a = v; return this; }
public Builder b(int v) { b = v; return this; }
public Builder c(int v) { c = v; return this; }
public Foo build() {
return new Foo(a, b, c);
}
}
private static class V {
int v;
V(int v) { this.v = v; }
}
public static class A extends V { A(int v) { super(v); } }
public static class B extends V { B(int v) { super(v); } }
public static class C extends V { C(int v) { super(v); } }
public static A a(int v) { return new A(v); }
public static B b(int v) { return new B(v); }
public static C c(int v) { return new C(v); }
public static void main(String[] args) {
Foo f1 = new Builder(a(1), b(2), c(3)).build();
Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
}
}
For other clients, static imports are your friends:
package myotherapp;
import myapp.Foo;
import static myapp.Foo.*;
public class Program {
public static void main(String[] args) {
Foo f1 = new Builder(a(1), b(2), c(3)).build();
Foo f2 = new Builder(a(1), b(2), c(3)).a(4).build();
}
}
Building on Jordão's idea, I came up with the following, which may arguably satisfy all requirements 1-6 even though there is some duplicate code in the type parameters. Essentially, the idea is to "pass around" the return types of each method by using type parameters to override the return value of the inherited methods. Even though the code is verbose and impractical, and actually requires Omega(n^3) characters if you extend it out to an arbitrary number of fields n, I'm posting it because I think it's an interesting use of the java type system. If anyone can find a way to reduce the number of type parameters (especially asymptotically), please post in the comments or write another answer.
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA<? extends BuilderB<?, ?>, ? extends BuilderC<?, ?>> newBuilder() {
return new BuilderFinal();
}
public static class BuilderA<B extends BuilderB<?, ?>, C extends BuilderC<?, ?>> {
private volatile int a;
#SuppressWarnings("unchecked")
public B a(int v) {
a = v;
return (B) this;
}
public int a() {
return a;
}
}
public static class BuilderB<B extends BuilderB<?, ?>, C extends BuilderC<?, ?>> extends BuilderA<B, C> {
private volatile int b;
#SuppressWarnings("unchecked")
public C b(int v) {
b = v;
return (C) this;
}
public int b() {
return b;
}
}
public static class BuilderC<B extends BuilderC<?, ?>, C extends BuilderC<?, ?>> extends BuilderB<B, C> {
private volatile int c;
#SuppressWarnings("unchecked")
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC<BuilderFinal, BuilderFinal> {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).a(2).build();
Foo f2 = newBuilder().a(1).a(2).c(3).build(); // compile error
Foo f3 = newBuilder().a(1).b(2).a(3).b(4).b(5).build(); // compile error
}
}
Why don't you want to override the setters in BuilderFinal? They would just need to downcast the super method:
public static class BuilderFinal extends BuilderC {
#Override
public BuilderFinal a(int v) {
return (BuilderFinal) super.a(v);
}
#Override
public BuilderFinal b(int v) {
return (BuilderFinal) super.b(v);
}
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}

making a lazy iterator for an arithmetic series?

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.

Java: Why does this method have side effects?

I have a method that is producing side effects, even though certain variables are marked final. Why is this? Perhaps I am confused about what final does.
#Test
public void testSubGraph() {
WeightedGraph<String, DefaultWeightedEdge> g = generateSimpleCaseGraph();
Graph<String, DefaultWeightedEdge> sub = ChooseRoot.subgraphInDirection(g, "alpha", "l");
assertEquals(g, generateSimpleCaseGraph()); //fails
}
public static <V, E extends DefaultEdge> Graph<V, E> subgraphInDirection(final Graph<V, E> g, final V start, final V sink) {
Graph<V, E> sub = removeEdges(g, start, sink);
return removeUnconnectedNodes(sub, start);
}
private static <Vertex, Edge extends DefaultEdge> Graph<Vertex, Edge> removeEdges(final Graph<Vertex, Edge> g, Vertex start, Vertex sink) {
final Set<Edge> outEdges = new HashSet<Edge>(g.edgesOf(start));
boolean removedEdge;
for (Edge e : outEdges) {
if (! (g.getEdgeTarget(e).equals(sink) || g.getEdgeSource(e).equals(sink))) {
removedEdge = g.removeEdge(e);
assert removedEdge;
}
}
return g;
}
private static <Vertex, Edge> Graph<Vertex, Edge> removeUnconnectedNodes(Graph<Vertex, Edge> g, Vertex start) {
ConnectivityInspector<Vertex, Edge> conn = new ConnectivityInspector<Vertex, Edge>((UndirectedGraph<Vertex, Edge>) g);
boolean removedVertex;
final Set<Vertex> nodes = new HashSet<Vertex>(g.vertexSet());
for (Vertex v : nodes) {
if (! conn.pathExists(start, v)) {
removedVertex = g.removeVertex(v);
assert removedVertex;
}
}
return g;
}
The final modifier only means that the reference cannot be reassigned. It does not prevent the object's state from being modified.
EDIT: Just for Tom:
public void doSomething1(Object arg)
{
arg = new Object(); // OK.
}
public void doSomething2(final Object arg)
{
arg = new Object(); // Compile error.
}
In both cases you can invoke methods on the object pointed to by arg, including methods that modify its state.
Dan has the right answer on final. What you are after is more like const in C++, which Java does not have. You can simulate it by doing this:
public class Foo
{
protected int x;
public Foo(final int val)
{
x = val;
}
public int getX()
{
return (x);
}
}
public class MutableFoo
extends Foo
{
public MutableFoo(final int val)
{
super(val);
}
public void setX(final int val)
{
x = val;
}
}
then do:
void bar(final Foo foo)
{
foo.setX(5); // will not compile
}
void bar(final MutableFoo foo)
{
foo.setX(5); // will compile
}
Not pretty, but it works. The trick is to make sure that none of the methods in the parent class (Foo) make any changes to the instance variables - only MutableFoo can have methods that allow the state to change.
Of course the best thing to do, as much as possible, is to write immutable classes (make all the variables final) and do not call methods on instance/class variables that have side effects, so that things cannot change

Categories