Can I modify a "referenced" integer variable? - java

I realize that if I pass an object as a parameter of a function and do changes to it, the changes "stay" with the object. But it is not the case for an integer.
public void start() {
int x = 100;
modify(x);
// I would like x to be 200 now. But it isn't :(
}
public void modify(int y) {
y *= 2;
}
So basically, is there a way to achieve what I wanted in the code above? Is it possible to modify an integer like that (like an object reference)?

While working with primitives there is no concept of "reference". But you may achieve what you want by doing something like below:
x = modify(x); may be code want.
Now x contains the results of modify(x) method invocation.

You cannot do that. Primitives are passed by value. (References are also passed by value. You can't modify an object reference; you can only modify the object that is referenced.) The best you can do is:
public void start() {
int [] x = {100};
modify(x);
// x[0] is now 200 :)
}
public void modify(int []y) {
y[0] *= 2;
}
The array reference x is passed by value, but you can modify the array elements. Note that passing an Integer won't help, because Integer objects are immutable.
Alternatively, you can redesign your method to return the doubled value and assign it in the calling code (as Nambari suggests).

A third possibility, beside passing an array or using a return value, would be to pass an object of some ValueHolder class with a getter and setter:
public class IntValueHolder
{
private int value;
public int getValue()
{
return this.value;
}
public void setValue(final int value)
{
this.value = value;
}
}
This is technically very similar to passing an array, but is IMHO a bit cleaner, i.e. it better describes your intent.

One thing you can do is get the return value of the modify() method and assign it to the variable as follows.
public void start() {
int x = 100;
x=modify(x);
}
public int modify(int y) {
return y *= 2;
}

Related

Does java cache method results?

If i have an immutable class like this:
public class MathClass {
private final int x;
public MathClass(int x) {
this.x = x;
}
public int calculateSomething() {
return Math.sqrt(x);
}
}
Does the jvm cache the result of calculateSomething() on the first call?
I have a more complicated calculation in the MathClass.
No it does not, only the object is stored within the cache
You could use your own caching solution, such as Spring's #Cacheable to store method results in cache
No, Java doesn't cache method results in general.
Some few methods of the Framework do this, but it's part of their implementation, e.g. Integer.valueOf(int).
c.f. JavaDoc:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range."
But with your implementation it would be easy to implement the "caching" by yourself: the class is immutable, that means the inputs don't change, so you can easily calculate the value on the first request and return the previously calculated value on subsequent requests:
public class MathClass {
private final int x;
private transient boolean calculated = false;
private transient int preCalcSomething;
public MathClass(int x) {
this.x = x;
}
public int calculateSomething() {
if (!calculated) {
preCalcSomething = Math.sqrt(x);
calculated = true;
}
return preCalcSomething;
}
}
I used the transient keyword here to mark that those two fields are not part of the "object state". Don't forget to exclude them from equals and hashCode calculations and maybe other state-depending methods!
If you are using an object instead of a primitive, I would use null as indicator for "not yet calculated" if that is a value that cannot be the actual result of the cached operation.
You could calculate it just once, and then return the result previously calculated.
public class MathClass {
private final int x;
private final int result;
public MathClass(int x) {
this.x = x;
this.result = Math.sqrt(x);
}
public int calculateSomething() {
return result;
}
}
The calculation will not be performed more than one time. This is not a cache but works as one in your scenario.

Is there a Integer class in c#?

We have Integer class in JAVA, but I couldn't find any equivalent class in C#? Does c# have any equivalent? If not, how do I get JAVA Integer class behavior in c#?
Why do I need this?
It is because I'm trying to migrate JAVA code to c# code. If there is an equivalent way, then code migration would be easier. To addon, I need to store references of the Integer and I don't think I can create reference of int or Int32.
C# has a unified type system, so int can be implicitly boxed into an object reference. The only reason Integer exists in Java is so that it can be converted to an object reference and stored in references to be used in other container classes.
Since C# can do that without another type, there's no corresponding class to Integer.
Code migration won´t work out of the box for any type of language without any manual changes. There are things such as a class Integer that simply does not exist within (C# why should it anyway, see recursives answer), so you´d have to do some work on your own. The nearest equivalent to what you´re after is Int32 or its alias int. However you may of course write your own wrapper-class:
public class Integer
{
public int Value { get; set; }
public Integer() { }
public Integer( int value ) { Value = value; }
// Custom cast from "int":
public static implicit operator Integer( Int32 x ) { return new Integer( x ); }
// Custom cast to "int":
public static implicit operator Int32( Integer x ) { return x.Value; }
public override string ToString()
{
return string.Format( "Integer({0})", Value );
}
}
The beauty of C# is that it has a unified type system. Everything derives from object, even primitive types. Because of this, all keywords are simply aliases for a corresponding class or struct. Java does not use a unified type system, so a separate Integer class is required to wrap the int primitive. In C# int is synonym for the Int32 struct.
What you're looking for has been right in front of you the whole time. Start using the dot notation directly on the int keyword (i.e. int.whatever()) to access the all goodness of the .NET version of the Javian Integer class.
I did some testing with Nullable types in a console application and it appears that they do not behave as you wish. For example:
static void Main(string[] args)
{
int? x = 1;
Foo(ref x);
Console.WriteLine(x);//Writes 2
}
private static void Foo(ref int? y)
{
y += 1;
var l = new List<int?>();
l.Add(y);
l[0] += 1;//This does not affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 2
Foo2(l);
}
private static void Foo2(List<int?> l)
{
l[0] += 1;
Console.WriteLine(l[0]);//writes 4
}
But if you roll your own generic class to wrap primitive/value types for use within your application you can get the behavior you are expecting:
public class MyType<T>
{
public T Value { get; set; }
public MyType() : this(default(T))
{}
public MyType(T val)
{
Value = val;
}
public override string ToString()
{
return this.Value.ToString();
}
}
static void Main(string[] args)
{
var x = new MyType<int>(1);
Foo(x);
Console.WriteLine(x);//Writes 4
}
private static void Foo(MyType<int> y)
{
y.Value += 1;
var l = new List<MyType<int>>();
l.Add(y);
l[0].Value += 1;//This does affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 3
Foo2(l);
}
private static void Foo2(List<MyType<int>> l)
{
l[0].Value += 1;
Console.WriteLine(l[0]);//writes 4
}
int, int? and System.Int32 are all struct and thus value types and does not compare to Java's Integer wrapper class which is a reference type.
System.Object class though a reference type can cause issue as boxing creates immutable object. In short, you can't alter a boxed value.
int a = 20;
Object objA = a; //Boxes a value type into a reference type, objA now points to boxed [20]
Object objB = objA; //Both objA & objB points to boxed [20]
objA = 40; //While objB points to boxed [20], objA points to a new boxed [40]
//Thus, it creates another ref type boxing a 40 value integer value type,
//Boxed values are immutable like string and above code does not alter value of previous boxed value [20]
Console.WriteLine($"objA = {objA}, objB={objB}");
//Output: objA = 40, objB=20
What exactly corresponds to Java's Integer is a custom generic wrapper class.
int a = 20;
Wrapper<int> wrapA = new Wrapper<int>(a);
Wrapper<int> wrapB = wrapA; //both wrapA and wrapB are pointing to [20]
wrapA.Value = 40; //Changing actual value which both wrapA and wrapB are pointing to
Console.WriteLine($"wrapA = {wrapA}, wrapB={wrapB}");
//Output: wrapA = 40, wrapB=40
Console.ReadKey();
Implementation of the wrapper class is given below:
public class Wrapper<T> where T : struct
{
public static implicit operator T(Wrapper<T> w)
{
return w.Value;
}
public Wrapper(T t)
{
_t = t;
}
public T Value
{
get
{
return _t;
}
set
{
_t = value;
}
}
public override string ToString()
{
return _t.ToString();
}
private T _t;
}
As pointed out in other answers, C# has a unified type system so everything derives from object. If you need to handle null values then use int? to specify that the integer object can be null.
c# have a integer type called int link is here
https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx

Why is the output not changed in this code snippet when I use the object form of int?

Given this code snippet:
class Ex1{
public static void main(String args[]){
int x = 10;
int y = new Ex1().change(x);
System.out.println(x+y);
}
int change(int x){
x=12;
return x;
}
}
I understand that the x in main won't get changed by the change method and return the value 22 because Java primitives are call-by-value. However, if I change all the int to Integer, making them objects and therefore theoretically call-by-value-of-reference, why does the program still return 22?
Is it possible to modify the method change such that it also modifies the variable x in main?
EDIT: new snippet
class Ex1{
public static void main(String args[]){
Integer x = 10;
Integer y = new Ex1().change(x);
System.out.println(x+y);
}
Integer change(Integer x){
x=12;
return x;
}
}
Both value and reference types are passed by-value in Java (see the Java Tutorials). This means that the passed-in reference still points at the same object as before the call, even if the internals of a method change the reference assigned to a method's parameter variable.
The primitive wrappers are all reference types, so there is no difference between their behaviour and the behaviour of any other reference type when passed as an argument to a method.
However, you can change the values inside a reference object, and those changes will be reflected after the method call completes, in the calling method. You can't do this with the primitive wrappers though: they are immutable.
public static void main(String[] args){
Foo parentFoo = new Foo(1);
System.out.println(parentFoo); // prints "instance 1, data is now 1"
changeReferenceFail(parentFoo); // prints "instance 2, data is now 2"
System.out.println(parentFoo); // prints "instance 1, data is now 1"
mutateReference(parentFoo); // prints "instance 1, data is now 3"
System.out.println(parentFoo); // prints "instance 1, data is now 3"
}
private static void changeReferenceFail(Foo myFoo) {
myFoo = new Foo(2); // assigns a new object to the myFoo parameter variable
System.out.println(myFoo);
}
private static void mutateReference(Foo myFoo) {
myFoo.setData(3); // changes the reference variable internals
System.out.println(myFoo);
}
...
class Foo {
private static int iidSeed = 0;
private int iid = 0;
private int data;
public Foo(int data) {
this.data = data;
this.iid = ++iidSeed;
}
public void setData(int data) { this.data = data; }
public String toString() {
return String.format("instance %d, data is now %d", this.iid, this.data);
}
}
You asked: "Is it possible to modify the method change such that it also modifies the variable x in main?".
You can either pass a reference object, and modify an internal field (as per mutateReference above). Or you can return a new integer and assign it to your local variableexactly as you are doing already.
Integer change(Integer x){
x=12;
return x;
}
Because this does not change what is stored inside the object Integer x, but assigns a new value to the variable x. It is not the original argument object being changed, but a new Integer object is created assigned to the variable formerly holding the original object.
As you said, when passing an object to a function, you actually pass the value of its reference. Thus, statements like myParam = something have no effect on the object passed to the method, only method calls such as myParam.mutate() can change its state. Nevertheless, Integer is an immutable class so you will not be able by any mean, to change the value of the Integer in the main.
You are passing the value of x to your method, that applies that value to another variable x. You would need to modify the correct instance of x to change it in main. This snippet changes x, although I'm sure you knew how to do this already.
class Ex1{
int x = 10;
public static void main(String args[]){
System.out.println(x);
changeX(15);
System.out.println(x);
}
void changeX(int newVal){
x=newVal;
}
}

How to implement a basic pointer

I know here is no pointer in Java. But how do I change a value in the calling scope? For instance, I want to write a function that takes an integer num, set the integer to 0 if it's greater than 21, otherwise do nothing.
In the main, my code is as follow:
int a=34;
KillOver21(a);
System.out.print(a);
I expect an 0.
Java is pass by value, so a copy of the parameter a is sent to the method, so modification to a in the method will not affect the original argument a in main
The max you can do is return int from KillOver21(a) method
int z = KillOver21(a); // This will return 0
System.out.print(z);
But you can achieve something like that with custom objects, say you have a class
class AHolder {
public int a;
}
then you can expect AHolder instance to change
public static void main(String [] args) {
AHolder a = new AHolder();
a.a = 34;
killOver21(a);
System.out.println(a.a);
}
public static void killOver21(AHolder b) {
if(b.a > 21) {
b.a = 0;
}
}
Since in the latter (even if its Pass by Value) , the reference is copied and both reference point to same object. So changes made inside the killOver21 method actually changes the object.
It is simply not possible, Java supports pass by value. int a's value will be copied to the function.
You could use Object instead of primitive where the reference value will be copied to your function by which you can get the actual object and modify it.
Fundamentally impossible in Java, period. int are immutable, and passed by value. You would need to create a mutable int type:
class MutableInt {
private int value;
public MutableInt(int value) { this.value = value; }
public getValue() { return this.value; }
public setValue(int value) { this.value = value; }
}
Then:
void KillOver21(MutableInt m) {
if(m.getValue() > 21) { m.setValue(0); }
}
However, be aware the mutable types that represent concepts that are defined by their value rather than their identity are generally an extremely bad idea. But, this is the only way to achieve what you're trying to achieve. Again, I caution you with the strongest words: what you're doing is a bad idea. You should find another way.
Doc, it hurts when I do this.
Then don't do that!
The simpliest way (quick&dirty) is to put value within an array
int holder[] = new int[]{ a};
KillOver21(holder)
System.out.printf( "value=[%d]", holder[0] );
void KillOver21(int holder[] ) {
holder[0] = 0;
}

How Java "pointers" work?

Lets say this is the C++ code:
void change(int& x){
x++;
}
or
void change2(int* a){
*a++;
}
Both will change the global x, right?
So how can I do something like that in java?
Specifically, I want to point to a Vector object
But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.
Thanks for
help!
In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.
Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:
void change(MutableInt x) {
x.increment();
}
The change to x will be visible to the caller.
Specifically, I want to point to a Vector object
When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.
Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.
With Java you cannot pass primitive types like int by reference, they are passed only by value.
The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.
Use an array of single value, like this
int[] value = new int[1];
value[0] = 2;
// call a method
obj.setValue(value);
// and in setValue
public void setValue(int[] value) {
value[0] = 5;
}
Or second approach use an holder class:
public class Holder<T> {
public T value;
public Holder(T value) {
this.value = value;
}
}
// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);
obj.setValue(h);
// and in setValue
public void setValue(Holder<Integer> h) {
h.value = 5;
}
In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:
public class IntHolder {
public int value;
public IntHolder(int value) {
this.value = value;
}
}
Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.
Thusly:
public int change(int x) {
return ++x;
// or
// return x + 1;
}
To test it:
int x = 2;
change(x);
System.out.println(x); // returns 2
x = change(x);
System.out.println(x); // returns 3
So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.
Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:
public class MyInt() {
public int i;
public void setInt(int i) {
this.i = i;
}
public int getInt() {
return this.i;
}
public int increment() {
this.i++;
}
}
You need to change your change function to have the above MyInt object as argument:
public void change(MyInt i) {
i.increment();
}
Usage:
MyInt x = new MyInt();
x.setInt(2);
change(x);
System.out.println(x.getInt); // returns 3
In your case you want to change a Vector object...
public void changeVector(Vector v) {
// anything you do with 'v' will change it even
// for the scope that called this method
}
// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method
Hope this all makes sense.
Both will change the global x, right?
So how can I do something like that in java? Specifically, I want to
point to a Vector object
The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?
Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)
public class Foo {
private static List<Integer> globalVector = new Vector<Integer>();
public static void add(int number){
globalVector.add(number);
}
// ... plus whatever other accessors to the global list that you need
}
Anywhere else in code:
Foo.add(23); // modifies the global vector
(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)
While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:
public class IntPointer {
public int value;
public IntPointer(int value) {
this.value = value;
}
}
Then elsewhere you could say:
public static void change(IntPointer ipoint) {
ipoint.value++;
}
public static void main(String[] args) {
IntPointer a = new IntPointer(10);
change(a);
}
This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:
public class ABPair {
private int a = 0;
private int b = 0;
public static void changeA() {
a++;
}
public static void changeB() {
b++;
}
}
So that elsewhere I can say:
public static void main(String[] args) {
ABPair ab = new ABPair();
if (ACondition) {
ab.changeA();
}
}
In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.
Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.
The major differences between a pointer in C and a reference in Java are:
You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one).
You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object.
For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).
So in a way Java references could be called "restricted pointers".

Categories