Recursively keeping count in Java - Simple - java

I know that I'm overlooking something incredibly fundamental and elementary, but I need help with creating a mean function that, using only one parameter (the list containing the integers- in this case), calculates the mean of the given integers.
public static double mean (Cons lst) {
int total = (Integer) lst.data;
int count = //something to keep count through the recursion
if(lst.next == null) {
return total / count;
}
else return mean(lst.next); // return statement isn't correct, need help here as well
}
Any help would be great. If the easiest way to explain is by writing the method itself, then that'd be wonderful, but I'm just trying to figure out how to recursively keep a running count without adding params.
Thanks a lot.

You are developing your recursive mean function as a method of a Java Class. Why don't you declare your count and total local variables as attributes of that class?
class Mean {
static int total = 0;
static int count = 0;
public static double mean (Cons lst) {
total += (Integer) lst.data;
count += 1;
if(lst.next == null) {
double ret = total/count;
total = 0;
count = 0;
return ret;
}
return mean(lst.next); // return statement isn't correct, need help here as well
}
}
Other option is to include "count" as a second parameter of your recursive method. If you don't want the user to pass more parameters use two methods: "mean" method, with one parameter (your list), should call the second method "recursiveMean(list, 0)" containing your implementation.
public static double mean (Cons lst) {
return recursiveMean (lst, 0, 0)
}
public static double recursiveMean (Cons lst, int count, int total) {
total += (Integer) lst.data;
count += 1;
if(lst.next == null) {
return total / count;
}
return mean(lst.next,count,total); // return statement isn't correct, need help here as well
}
Nevertheless, I don't see why you are implementing a mean function as a recursive function unless it is some kind of educational exercise.

Related

Implementing a generic map using a hash table in Java

Post Details
In a data structures course, I was given Java source code for a "quadratic probing hash table" class and asked to implement a generic map (with get and put methods) and store the key/definition pairs in a hash table. I understand the material when reading the book but find it difficult to implement in a programming language (Java). I think part of the problem is understanding exactly what the question requires and part is deficiency in Java programming experience. I'm hoping to receive some suggestions for how I can approach problems like this and fill in whatever Java knowledge I'm missing.
Some questions I've had
What is the function of the hash table class in relation to the generic map I'm supposed to create? The hash table has several methods including get, insert, remove, rehash, etc... Is the purpose of the hash table to generate a hash value to use as a key in the map class? Are keys and definitions stored in the hash table or will they be stored in the map? What's the point of making a map if the hash table already does all of this?
Can someone help me understand how to approach problems like this? What are some references that might help me, either specifically with this question or with understanding how to effectively and methodically complete this type of exercise?
I appreciate whatever help I can get. I'm including code from the book to help illustrate the problem.
Quadratic Probing Hash Table Code From Textbook
public class QuadraticProbingHashTable<AnyType> {
public QuadraticProbingHashTable() {
this(DEFAULT_TABLE_SIZE);
}
public QuadraticProbingHashTable(int size) {
allocateArray(size);
doClear();
}
public boolean insert(AnyType x) {
int currentPos = findPos(x);
if(isActive(currentPos)) return false;
array[currentPos] = new HashEntry<>(x, true);
theSize++;
if(++occupied > array.length / 2) rehash();
return true;
}
private void rehash() {
HashEntry<AnyType>[] oldArray = array;
allocateArray(2 * oldArray.length);
occupied = 0;
theSize = 0;
for(HashEntry<AnyType> entry : oldArray)
if(entry != null && entry.isActive) insert(entry.element);
}
private int findPos(AnyType x) {
int offset = 1;
int currentPos = myhash(x);
while(array[currentPos] != null && !array[currentPos].element.equals(x)) {
currentPos += offset;
offset += 2;
if(currentPos >= array.length) currentPos -= array.length;
}
return currentPos;
}
public boolean remove(AnyType x) {
int currentPos = findPos(x);
if(isActive(currentPos)) {
array[currentPos].isActive = false;
theSize--;
return true;
} else return false;
}
public int size() {
return theSize;
}
public int capacity() {
return array.length;
}
public boolean contains(AnyType x) {
int currentPos = findPos(x);
return isActive(currentPos);
}
public AnyType get(AnyType x) {
int currentPos = findPos(x);
if(isActive(currentPos)) return array[currentPos].element;
else return null;
}
private boolean isActive(int currentPos) {
return array[currentPos] != null && array[currentPos].isActive;
}
public void makeEmpty() {
doClear( );
}
private void doClear() {
occupied = 0;
for(int i = 0; i < array.length; i++) array[i] = null;
}
private int myhash(AnyType x) {
int hashVal = x.hashCode();
hashVal %= array.length;
if(hashVal < 0) hashVal += array.length;
return hashVal;
}
private static class HashEntry<AnyType> {
public AnyType element;
public boolean isActive;
public HashEntry(AnyType e) {
this(e, true);
}
public HashEntry(AnyType e, boolean i) {
element = e;
isActive = i;
}
}
private static final int DEFAULT_TABLE_SIZE = 101;
private HashEntry<AnyType>[] array;
private int occupied;
private int theSize;
private void allocateArray(int arraySize) {
array = new HashEntry[nextPrime(arraySize)];
}
private static int nextPrime(int n) {
if(n % 2 == 0) n++;
for(; !isPrime(n); n += 2) ;
return n;
}
private static boolean isPrime( int n ) {
if(n == 2 || n == 3) return true;
if(n == 1 || n % 2 == 0) return false;
for(int i = 3; i * i <= n; i += 2)
if(n % i == 0) return false;
return true;
}
}
Map Skeleton From Textbook
class Map<KeyType,ValueType> {
public Map()
public void put(KeyType key, ValueType val)
public ValueType get(KeyType key)
public boolean isEmpty()
public void makeEmpty()
private QuadraticProbingHashTable<Entry<KeyType,ValueType>> items;
private static class Entry<KeyType,ValueType> {
KeyType key;
ValueType value;
}
}
Generally, what you're facing is a problem of implementing a given interface. The Map is the interface - the HashTable is a means of implementing it, the underlying data structure.
However, I understand your confusion as the definition of the HashTable that you were provided seems ill-suited for the job as it does not seem to have an option to use a custom key (instead always relying on the object's hash code for calculating the hash) nor does it have an option to have a custom HashEntry. As the question is specified, I would say the answer is "you can't". Generally, implementing a Map on a HashTable comes down to handling collisions - one approach, which is not very effective but usually works, is that whenever you find a collision (a case where you have differing keys but the same hashes), you rehash the entire table until the collision is no longer there. The more commonly adopted answer is having a multi-level hashtable, which basically recursively stores a hashtable (calculating a different hash function) on each level. Another method is having a hashtable of arrays - where the arrays themselves store lists of elements with the same hash - and rehashing if the number of collisions is too large. Unfortunately, neither of those solutions is directly implementable with the sample class that you were provided. Without further context, I cannot really say more, but it just seems like a badly designed exercise (this is coming from someone who does occasionally torture students with similar things).
An way of hacking this within your framework is creating a Pair type whose hashCode function just calculates key.hashCode(). This way, as a value you could store an array (and then use the array approach I mentioned above) or you could store a single element (and then use the rehash approach). In either solution, solving the collision handling is the most difficult element (you have to handle cases where the HashTable contains() your Pair, but the value part of the pair doesn't equals() the element that you want to insert.

creating java generic data structure

I am building a data structure to learn more about java. I understand this program might be useless.
Here's what I want. I want to create a data structure that store smallest 3 values. if value is high, then ignore it. When storing values than I also want to put them in correct place so I don't have to sort them later. I can enter values by calling the add method.
so let's say I want to add 20, 10, 40, 30 than the result will be [10,20,30]. note I can only hold 3 smallest values and it store them as I place them.
I also understand that there are a lot of better ways for doing this but again this is just for learning purposes.
Question: I need help creating add method. I wrote some code but I am getting stuck with add method. Please help.
My Thinking: we might have to use a Iterator in add method?
public class MyJavaApp {
public static void main(String[] args){
MyClass<Integer> m = new MyClass<Integer>(3);
m.add(10);
m.add(20);
m.add(30);
m.add(40);
}
}
public class MyClass<V extends Comparable<V>> {
private V v[];
public MyClass(int s){
this.v = (V[])new Object[s];
}
public void add(V a){
}
}
Here is a rough sketch of the add method you have to implement.
You have to use the appropriate implementation of the compareTo method when comparing elements.
public void add(V a){
V temp = null;
if(a.compareTo( v[0]) == -1 ){
/*
keeping the v[0] in a temp variable since, v[0] could be the second
smallest value or the third smallest value.
Therefore call add method again to assign it to the correct
position.
*/
temp = v[0];
v[0] = a;
add(temp);
}else if(a.compareTo(v[0]) == 1 && a.compareTo(v[1]) == -1){
temp = v[1];
v[1] = a;
add(temp);
}else if(a.compareTo(v[1]) == 1 && a.compareTo(v[2]) == -1){
temp = v[2];
v[2] = a;
add(temp);
}
}
Therefore the v array will contain the lowerest elements.
Hope this helps.
A naive, inefficient approach would be (as you suggest) to iterate through the values and add / remove based on what you find:
public void add(Integer a)
{
// If fewer than 3 elements in the list, add and we're done.
if (m.size() < 3)
{
m.add(a);
return;
}
// If there's 3 elements, find the maximum.
int max = Integer.MIN_VALUE;
int index = -1;
for (int i=0; i<3; i++) {
int v = m.get(i);
if (v > max) {
max = v;
index = i;
}
}
// If a is less than the max, we need to add it and remove the existing max.
if (a < max) {
m.remove(index);
m.add(a);
}
}
Note: this has been written for Integer, not a generic type V. You'll need to generalise. It also doesn't keep the list sorted - another of your requirements.
Here's an implementation of that algorithm. It consists of looking for the right place to insert. Then it can be optimized for your requirements:
Don't bother looking past the size you want
Don't add more items than necessary
Here's the code. I added the toString() method for convenience. Only the add() method is interesting. Also this implementation is a bit more flexible as it respects the size you give to the constructor and doesn't assume 3.
I used a List rather than an array because it makes dealing with generics a lot easier. You'll find that using an array of generics makes using your class a bit more ugly (i.e. you have to deal with type erasure by providing a Class<V>).
import java.util.*;
public class MyClass<V extends Comparable<V>> {
private int s;
private List<V> v;
public MyClass(int s) {
this.s = s;
this.v = new ArrayList<V>(s);
}
public void add(V a) {
int i=0;
int l = v.size();
// Find the right index
while(i<l && v.get(i).compareTo(a) < 0) i++;
if(i<s) {
v.add(i, a);
// Truncate the list to make sure we don't store more values than needed
if(v.size() > s) v.remove(v.size()-1);
}
}
public String toString() {
StringBuilder result = new StringBuilder();
for(V item : v) {
result.append(item).append(',');
}
return result.toString();
}
}

Understanding Java methods

So, I'm very new to Java, I have a summer college course and we're on functions or methods and I'm having a bit of trouble understanding them.
There is a question on a lab I'm having a little trouble with:
"Write a method called MaxOfThree that accepts three integer
parameters and returns the largest of the three."
This is what I have so far but I'm not sure whats wrong. I added the print statement at the end because I wasn't getting a return value when I ran it but now I'm getting errors and it's not compiling. If you could help me understand methods a bit more I'd greatly appreciate it. For instance how the parameters work and calling it and if what's included in the function call is correct and how that works. I just get so confused when I read through the material and was hoping for an explanation in more layman's terms. Thanks for any help, here is what I have so far.
public class Test {
public static void main(String[] args) {
int a = 2, b = 3, c = 4;
int maxValue = max3(a, b, c);
}
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
return max;
System.out.println(max);
}
}
Here are the errors I'm receiving just in case...
Test.java:16: error: unreachable statement
System.out.println(max);
^
Test.java:17: error: missing return statement
}
^
2 errors
You can't have a statement after the return statement, or to be more exact - a statement imediatelly after a return statement (such as your println) can never be executed, and is therefore an error.
The println should be before the return statement.
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
I suggest You to change those if statements into one simple for loop with simple int[] vector. This solution is much more elegant and flexible. Additionally, You initialized and not used anywhere int maxValue = max3(a, b, c); in Your code.
public class Demo {
public static void main(String args[]) {
int[] numbers = new int[] {2, 3, 4};
System.out.println(maxValue(numbers));
}
public static int maxValue(int[] n) {
int max = n[0];
for (int i = 1; i < n.length; i++) {
if (n[i] > max) {
max = n[i];
}
}
return max;
}
}
But let's bow for a moment on the problem of methods implementation in Java.
At the begining of Your journey through the vastness of the Java realm You should get familiar with two types of methods: 1) void methods, and 2) return methods. The first ones are responsible for doing something without returning any value. We can for example use them for setting values of the fields of our application, initializing GUI, or other operations. The use of the void method can look like this:
/* method declaration */
void setValue(int value) {
someField = value;
}
/* method invocation */
setValue(5);
After invocation of setValue(5) the value of the someField object will be 5. However, you have to remember about type compatibility, so in this case someField can not be e.g of String type.
Second method type mentioned above, i.e return method is very useful, when you expect the method to give You an output, e.g in result of some operations conducted on the data You've given to Your method. But of course it's not necessary, to provide for the return method an input. Anyway, the use of return method can look like this:
/* method returns text You've given to it */
String getText(String text) {
return text;
}
/* method returns result of addition of three given int's */
int calculate(int a, int b, int c) {
return a + b + c;
}
/* method return a random number */
int createRandomNumber() {
Random random = new Random();
return random.nextInt();
}
You can easily see, that there is plenty of space for improvisation. Basicaly and in summary, void methods can work with given objects, for example can set values and conduct other operations, but thay don't return any STRAIGHT results You can work with. Return methods, from the other hand, provide You physical results, which You can use in further operations, or even in other methods, for example:
import java.util.Random;
public class Demo {
private static int someValue;
public static void main(String args[]) {
setValue(calculate(
createRandomNumber(),
createRandomNumber(),
createRandomNumber()));
System.out.println(someValue);
}
public static void setValue(int value) {
someValue = value;
}
public static int calculate(int a, int b, int c) {
return a + b + c;
}
public static int createRandomNumber() {
Random random = new Random();
return random.nextInt();
}
}
The problem is that the compiler detects that execution will never reach the System.out.println line, so it refuses to compile. The line return max; effectively ends the method, so nothing more will run after that.
You should move return max; to below the System.out.println line.
Swap your last 2 lines (return and System).
It should be like this, return max statement should be the last line in your method if you want to print something, because return statement goes back or invoke the line that called him,so your print statement is not reach.
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
You need to put
System.out.println(max);
before:
return max;
the reason is your return unconditionally ends the function and therefore the compiler won't reach the println causing a compile error.
You have a System.out.println() statement after the return. return ends the method and so the System.out.println() will never happen because the method will have ended. That's why you are getting errors. Put the System.out.println() before the return:
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
As already been said, after you return something, the method will end. So your output in the last line of the method will not be executed, so remove it.
You can print the returned value of the method when you write the following outside of the method:
System.out.println("highest value:" + max3(a,b,c));
So now, the 3 values are given to the method which can do something with them now. After it did the calculations, the method returns a value, which can now be printed to the console for example.
The issue with the code you provided is that you're trying to print to the console, after you use your return statement. This causes your program to never reach that line: System.out.println(max);

Is it possible to reasonably emulate yield-syntax, perhaps with help of Java 8?

I was experimenting with this question today, from Euler Problems:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I thought about it and it can of course be done with for-loops, however I want to use Java 8 as it opens up new options.
However first of all, I do not know how to generate an IntStream that produces such elements, so I still ended up using normal for-loops:
public class Problem4 extends Problem<Integer> {
private final int digitsCount;
private int min;
private int max;
public Problem4(final int digitsCount) {
this.digitsCount = digitsCount;
}
#Override
public void run() {
List<Integer> list = new ArrayList<>();
min = (int)Math.pow(10, digitsCount - 1);
max = min * 10;
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
int sum = i * j;
if (isPalindrome(sum)) {
list.add(sum);
}
}
}
result = list.stream().mapToInt(i -> i).max().getAsInt();
}
private boolean isPalindrome(final int number) {
String numberString = String.valueOf(number);
String reversed = new StringBuilder(numberString).reverse().toString();
return (numberString.equals(reversed));
}
#Override
public String getName() {
return "Problem 4";
}
}
As you can see I might be a bit lazy, bit really the IntStream::max is a very nice method and I think it is better to use that, as to write it yourself.
Here comes the issue though, I need to have a list now to be able to obtain the maximum in this manner, which means I need to store data, where I really should not do so.
So, the question now, would it be possible to implement this in Java 8?
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
yield i * j;
}
}
And then out of that method create an PrimitiveIterator.OfInt (unboxes version of Iterator<Integer>, or create an IntStream directly?
Then getting the answer with streamFromYield.filter(this::isPalindrome).max().getAsInt() would be really easy to implement.
Lastly, I know this question has been asked before, however the last time is already quite a bit ago and now Java 8 is going to happen very soon, where they have added as big concept Stream<T> and the new language construct, called lambdas.
So making such code may be very different now than when people were making it for Java 6 or 7.
Well, I think we've gotten carried away using the Streams API from the "outside," using flatMap, optimizing the palindrome-finding algorithm, etc. See answers from Boris the Spider and assylias. However, we've sidestepped the original question of how to write a generator function using something like Python's yield statement. (I think the OP's nested-for example with yield was using Python.)
One of the problems with using flatMap is that parallel splitting can only occur on the outermost stream. The inner streams (returned from flatMap) are processed sequentially. We could try to make the inner streams also parallel, but they'd possibly compete with the outer ones. I suppose nested splitting could work, but I'm not too confident.
One approach is to use the Stream.generate or (like assylias' answer) the Stream.iterate functions. These create infinite streams, though, so an external limit must be supplied to terminate the stream.
It would be nice if we could create a finite but "flattened" stream so that the entire stream of values is subject to splitting. Unfortunately creating a stream is not nearly as convenient as Python's generator functions. It can be done without too much trouble, though. Here's an example that uses the StreamSupport and AbstractSpliterator classes:
class Generator extends Spliterators.AbstractIntSpliterator {
final int min;
final int max;
int i;
int j;
public Generator(int min, int max) {
super((max - min) * (max - min), 0);
this.min = min;
this.max = max;
i = min;
j = min;
}
public boolean tryAdvance(IntConsumer ic) {
if (i == max) {
return false;
}
ic.accept(i * j);
j++;
if (j == max) {
i++;
j = min;
}
return true;
}
}
public static void main(String[] args) {
Generator gen = new Generator(100, 1000);
System.out.println(
StreamSupport.intStream(gen, false)
.filter(i -> isPalindrome(i))
.max()
.getAsInt());
}
Instead of having the iteration variables be on the stack (as in the nested-for with yield approach) we have to make them fields of an object and have the tryAdvance increment them until the iteration is complete. Now, this is the simplest form of a spliterator and it doesn't necessarily parallelize well. With additional work one could implement the trySplit method to do better splitting, which in turn would enable better parallelism.
The forEachRemaining method could be overridden, and it would look almost like the nested-for-loop-with-yield example, calling the IntConsumer instead of yield. Unfortunately tryAdvance is abstract and therefore must be implemented, so it's still necessary to have the iteration variables be fields of an object.
How about looking at it from another direction:
You want a Stream of [100,1000), and for each element of that Stream you want another Stream of that element multiplied by each of [100, 1000). This is what flatMap is for:
public static void main(final String[] args) throws Exception {
OptionalInt max = IntStream.range(100, 1000).
flatMap((i) -> IntStream.range(i, 1000).map((j) -> i * j)).
unordered().
parallel().
filter((i) -> {
String forward = Integer.toString(i);
String backward = new StringBuilder(forward).reverse().toString();
return forward.equals(backward);
}).
max();
System.out.println(max);
}
Not sure if getting a String and then the reverse is the most efficient way to detect palindromes, off the top of my head this would seem to be faster:
final String asString = Integer.toString(i);
for (int j = 0, k = asString.length() - 1; j < k; j++, k--) {
if (asString.charAt(j) != asString.charAt(k)) {
return false;
}
}
return true;
It gives the same answer but I haven't put it under an rigorous testing... Seems to be about 100ms faster on my machine.
Also not sure this problem is big enough for unordered().parallel() - removing that gives a little boost to speed too.
Was just trying to demonstrate the capabilities of the Stream API.
EDIT
As #Stuart points out in the comments, as multiplication is commutative, we only need to IntStream.range(i, 1000) in the sub-stream. This is because once we check a x b we don't need to check b x a. I have updated the answer.
There always have been ways to emulate that overrated yield feature, even without Java 8. Basically it is about storing the state of an execution, i.e. the stack frame(s), which can be done by a thread. A very simple implementation could look like this:
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class Yield<E> implements Iterable<E> {
protected interface Flow<T> { void yield(T item); }
private final class State implements Runnable, Iterator<E>, Flow<E> {
private E nextValue;
private boolean finished, value;
public synchronized boolean hasNext() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
return value;
}
public synchronized E next() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
if(!value) throw new NoSuchElementException();
final E next = nextValue;
value=false;
notify();
return next;
}
public void remove() { throw new UnsupportedOperationException(); }
public void run() {
try { produce(this); }
finally {
synchronized(this) {
finished=true;
notify();
}
}
}
public synchronized void yield(E next) {
while(value) try { wait(); } catch(InterruptedException ex){}
nextValue=next;
value=true;
notify();
}
}
protected abstract void produce(Flow<E> f);
public Iterator<E> iterator() {
final State state = new State();
new Thread(state).start();
return state;
}
}
Once you have such a helper class, the use case will look straight-forward:
// implement a logic the yield-style
Iterable<Integer> y=new Yield<Integer>() {
protected void produce(Flow<Integer> f) {
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
f.yield(i * j);
}
}
}
};
// use the Iterable, e.g. in a for-each loop
int maxPalindrome=0;
for(int i:y) if(isPalindrome(i) && i>maxPalindrome) maxPalindrome=i;
System.out.println(maxPalindrome);
The previous code didn’t use any Java 8 features. But it will allow using them without the need for any change:
// the Java 8 way
StreamSupport.stream(y.spliterator(), false).filter(i->isPalindrome(i))
.max(Integer::compare).ifPresent(System.out::println);
Note that the Yield support class above is not the most efficient implementation and it doesn’t handle the case if an iteration is not completed but the Iterator abandoned. But it shows that such a logic is indeed possible to implement in Java (while the other answers convincingly show that such a yield logic is not necessary to solve such a problem).
I'll give it a go. Version with a loop then with a stream. Although I start from the other end so it's easier because I can limit(1).
public class Problem0004 {
public static void main(String[] args) {
int maxNumber = 999 * 999;
//with a loop
for (int i = maxNumber; i > 0; i--) {
if (isPalindrome(i) && has3DigitsFactors(i)) {
System.out.println(i);
break;
}
}
//with a stream
IntStream.iterate(maxNumber, i -> i - 1)
.parallel()
.filter(i -> isPalindrome(i) && has3DigitsFactors(i))
.limit(1)
.forEach(System.out::println);
}
private static boolean isPalindrome(int n) {
StringBuilder numbers = new StringBuilder(String.valueOf(n));
return numbers.toString().equals(numbers.reverse().toString());
}
private static boolean has3DigitsFactors(int n) {
for (int i = 999; i > 0; i--) {
if (n % i == 0 && n / i < 1000) {
return true;
}
}
return false;
}
}

How to tell if an int has been changed

I want to know how to tell if an int has been changed (during the program).
Like with an if statement.
int i = 2;
int a = 1;
while(1 < 2) {
if(i % 100 == 0) i++;
}
if(i //Then checks if it changed) {
System.out.println("Changed :D");
}
Is there a way to tell if the variable i is changed DURING the program?
Since this is Java, are these variables data members of a class? In that case give them private access and provide getters and setters. Your setter can notify you if you so desire.
int i = 0;
boolean valueChanged = false;
while(some good condition) {
if (i % 100 == 0) {
i++;
valueChanged = true;
}
}
if(valueChanged) {
System.out.println("Changed :D");
}
// Your int variable
int i = 0;
// A scratch variable
int prev_value_of_i = i;
// Call this code to check whether i has changed since last call
if(i != prev_value_of_i) {
System.out.println("Changed :D");
prev_value_of_i = i;
}
Keep track of the original value of i in a separate variable and compare i to that?
This seems redundant, since the programmer should know when and where values are stored. If you don't, maybe step through with a debugger? #shoover's answer is the most flexible, handling however many unexpected times you might change the value without requiring adding lines of code inside your infinite loop.
class TalkativeInt{
private int x;
TalkativeInteger(int x){
this.x = x;
}
public void set(int a){
System.out.println("Changed!! "+x+" to "+a);
x = a;
}
public int get(){
//System.out.println("Accessed - that tickles");
return x;
}
}

Categories