views:

45

answers:

2

I would like to go from one number to another. For example if I started at 6 and my goal was 10 I want a function that on every pass would bring me from 6 towards 10 or if I had the number 14 and my goal was 9 it would count down from 14 towards 9.So far I have (this is written in Processing a Java Api but there is essentially no difference from regualr Java, draw is just a continuous loop)

int x=100;
void draw(){
  x=towards(x,10);
  println(x);

}

int towards(int current ,int target){
  if(current!=target){
    if (current <target){
      current=current+1;
    }
    else {
      current=current-1;
    }
  }
  return current;
}

this gives me the results I would like but I would like to have everything in side of the towards() function. When I replace X with a variable it of course resets it self to the static variable.

To sum it up how can I pass a variable to a function and have that variable thats been passed change on every subsequent pass. I have looked into recursion as a solution but that of just brings me to a final solution. I can pass the count to an array but wouldn't like to do that either.

A: 

Java always passes int arguments by value. If you want to keep state around (particularly writable state) then keep it in an object and (probably) make towards() a method of that class.

Donal Fellows
that would definitely work...Does Java have anything similar to a Python generator? Should I like towards objects as a solution more often? I would hate to create an object for this every time I needed it.
Doodle
Java's an OO language with a pretty efficient memory allocation system so might as well use it. :-) I've seen things like Python generators, but it might be simpler to just make an `Iterator` if you're thinking of using the generator to return a sequence of values.
Donal Fellows
@Doodle, for a generator, see my solution; I have created a range iterator that you can use.
Michael Aaron Safyan
+2  A: 

Java uses pass-by-value, and so you cannot change the parameters (although if the parameters is a user-defined object, you can change the object pointed-to by the parameter, but not the parameter, itself).

One thing you might consider, though, is to create an iterator type interface:

// RangeIterator.java
public class RangeIterator implements Iterator<Integer>
{
   public RangeIterator(int first, int last){
       _first = first;
       _last = last;
       if ( _first <= _last ){
           _step = 1;
       }else{
           _step = -1;
       }
   }

   public RangeIterator(int first, int last, int step){
       if ( step == 0 ){
            throw new IllegalArgumentException("Step must be non-zero.");
       }
       _first = first;
       _last = last;
       _step = step;
   }

   public boolean hasNext(){
       if ( _step < 0 ){
           return _first > _last;
       } else {
           return _first < _last;
       }
   }

   public Integer next(){
       int result = _first;
       _first += _step;
       return result;
   }

   public void remove(){
       throw new UnsupportedOperationException("Not implemented.");
   }

   private int _first;
   private int _last;
   private int _step;
}

// Range.java
public class Range implements Iterable<Integer>
{
     public Range(int first, int last){
       _first = first;
       _last = last;
       if ( _first <= _last ){
           _step = 1;
       }else{
           _step = -1;
       }
     }

     public Range(int first, int last, int step){
       if ( step == 0 ){
            throw new IllegalArgumentException("Step must be non-zero.");
       }
       _first = first;
       _last = last;
       _step = step;
     }

     public Iterator<Integer> iterator(){ 
           return new RangeIterator(_first,_last,_step); 
     }

     private int _first;
     private int _last;
     private int _step;
}

With the code above, you could then conveniently write something like:

Range range = new Range(x,100);
for (int val : range){
    println(val);
}

Since I see that you come from a Python background, this should feel very much like:

for val in xrange(x,100):
    print val;

You can implement the Iterable and Iterator interfaces in order to provide your own generators that can be used in the Java for-each loops. Basically, for (Type identifier1 : identifier2) iterates through the contents of identifier2 which needs to be an Iterable type, and on each iteration assigns the current element to identifier1. The loop is just syntactic sugar for iterating over identifier2.iterator().

Michael Aaron Safyan