1

1) When Java encounters int[], does it actually understand it as Integer[], I mean array can only hold references, not primitives ?

2) When it comes to return two immutable integers from a function, are those two ways equivalent?

int a, b;
...
int[] returnVal = {a, b};
return(returnVal);

vs.

Integer a, b;
...
Integer[] returnVal = {a, b};
return(returnVal);

3) What is the standard practice to return two immutable integers?


Edits:

I'm wondering if "immutable" is actually the correct term to use as my question is about how to return safely a pair of integer values to a caller and at the same time preventing the caller to change the original values without using unnecessary clone().

By trying different pieces of code, the short answer to point #2 seems to be that you can safely return the values as int[] or Integer[]. The caller may change the elements of the returned array, but not the initial values.

Answers below provide explanations for that, and valuable clues for points #1 and #3. As I cannot select multiple answers as correct, I've selected the most useful for me, but I thank everyone for their assistance.

mins
  • 6,478
  • 12
  • 56
  • 75
  • Integer and int are automatically interchangeable look into autoboxing/unboxing http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html – codeMan Mar 27 '14 at 06:56
  • I understand that, because of autoboxing, "Integer[] returnVal = {1,2}" compiles with no error. What I would like to know is if "int[] =" is actually compiled exactly like "Integer[] =" (and that there is no actual thing like array of values.) – mins Mar 27 '14 at 07:07
  • No, they are not. An `int[]` stores only primitives, not Objects, so it uses much less memory. The downside of this is that it is not easily managed by other Collection objects and APIs, which handle `Object[]`; You will have to use Apache, or another library, to do nice things with `int[]`. – torquestomp Mar 27 '14 at 07:13
  • @Approaching minimums No, `int[]` will not be converted to `Integer[]`. Consider this example : `int[] returnVal = {new Integer(5), new Integer(7)};` will be converted to something like this : `int[] returnVal = {5/*primitive*/, 7/*primitive*/};` – codeMan Mar 27 '14 at 07:20
  • Ok, I wasn't aware of existence of primitives array, I though an array would always be a list of references and that autoboxing would apply to int elements. So returning int[] v = {a/*int*/, b/*int*/]} is safe because there is no element reference returned, and returning Integer[] v = {a/*Integer*/, b/*Integer*/} is also safe, in spite of references being returned, because elements returned are immutable. Right? – mins Mar 27 '14 at 07:33

5 Answers5

1

The standard practice is:

public class NameThatDescribesWhatAPairOfIntegersSymbolicallyRepresents {
  private final int nameDescribingFirstInteger'sRole;
  private final int nameDescribingSecondInteger'sRole;

  public NameThatDescribesWhatAPairOfIntegersSymbolicallyRepresents(
      int firstInteger, int secondInteger) {
    nameDescribingFirstInteger'sRole = firstInteger;
    nameDescribingSecondInteger'sRole = secondInteger;
  }

  public int getDescriptiveNameOfFirstInteger() {
    return nameDescribingFirstInteger'sRole;
  }

  public int getDescriptiveNameOfSecondInteger() {
    return nameDescribingSecondInteger'sRole;
  }
}

Anything less will lead to a poor, disgruntled coder two years from now, staring at:

status = result[0] + 2 * result[1];

And proceeding to tear his hair out as he mouths to himself "What the !@#$ is int[] result"?

=== Edit ===

Rant aside, the answers to your questions are:

1) No, these are totally different things. Primitives and Objects have different handles, consume different amounts of memory, and behave in different ways.

2) See (1) - no.

Additionally, no array - be it int[], or Integer[] - can ever be immutable. Java arrays are defined to be mutable always, you can't stop the caller from changing out the elements in an array. The only way to have a method return an "Immutable" array is if it generates a brand new copy every time it is called, and never hands out internal, mutable data.

3) See above

torquestomp
  • 3,304
  • 19
  • 26
  • There is also standard implementations like apache common ImmutablePair, that can be reused for that – mavarazy Mar 27 '14 at 07:02
  • Pair classes are cancerous, and not much better than an int[2] - you at least enforce the length, 2, of the data... but 'firstItem' and 'secondItem' have no inherent meaning. – torquestomp Mar 27 '14 at 07:03
  • @torquestomp: arrays are mutable, okay. My question is not how to return an immutable int[], but how to return two immutable int (maybe by the use of a mutable array). – mins Mar 27 '14 at 07:43
  • The immutability of what you return has nothing to do with how it's returned (unless you're returning a mutable reference to internal data, such as returning a non-copied array), it has to do with how the class manages its data. An int[], Integer[], and DescriptiveName...BlahBlahBlah can all be used as return formats for both mutable and immutable data. – torquestomp Mar 27 '14 at 17:22
  • @torquestomp: It would be nice if languages allowed one to define a "pair with named members", but most languages have no such feature. Using a pair type versus a custom type loses the prospective benefit of having named elements, but gains the advantage of not requiring a reader to examine the type to see if it adds any semantics beyond aggregating two things. To my mind, that advantage can often outweigh the disadvantage. – supercat Mar 27 '14 at 22:13
1

No they are not identical. The compiler uses a trick called auto-boxing to make a and b switch between int and integers. It applies Integer.valueOf(primitiveInt) or integerInstance.intvalue() on demand and automatically.

The best semantics is whether any of the numbers can be absent. That only works for Integer, not int

There is a suitable Pair class in apache commons lang:

http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/tuple/Pair.html

Along with an immutable one.

Or create your own custom one:

Using Pairs or 2-tuples in Java

Community
  • 1
  • 1
Niels Bech Nielsen
  • 4,777
  • 1
  • 21
  • 44
1

When Java encounters int[], does it actually understand it as Integer[], I mean array can only hold references, not primitives ?

No for returning int[] collection of integer values(Primitive types) array is not same as Integer[] Collection of Integer Objects (Objects)

For Second Question.

No both are still not same because it's completely depend on return type of method. As you can not return int[] where return type of method is Integer[].

For immutable return i want to add that you don't modified the object, rather you pointed the reference to a different object this happens only in Integer not in int.

In the sense of it depends on your code but if you ask which one is better i will say wrapping of int to Integer will be better in practice.

akash
  • 22,664
  • 11
  • 59
  • 87
  • Let's say I can choose the return type freely, and that my only constraint is to return 2 immutable integers (int or Integer). Your suggestion is to return an array of Integer or wrapped int. Sounds it makes sense to me with your and other's explanations in this page. Can you confirm that if I return an array of int elements, I'm wrong, because the int elements are mutable? Thanks. – mins Mar 27 '14 at 07:55
  • Well I won't say you are wrong but my intention to this is there can be a performance degradation due to boxing and unboxing, as you can feel the overhead of converting between these.Moreover Integer class adds additional methods that can be very useful while you can not do that with int as system need to box it first to use methods. – akash Mar 27 '14 at 08:09
  • Sorry for bothering again... I understand primitives are lighter and should be favored when possible. But my point here is about returning the array of int is wrong because elements are mutable and I'll not achieve my goal to return immutable values. Thanks. – mins Mar 27 '14 at 08:21
  • Yes you will as I know.Let me clear this A mutable object is an object that can be modified after it's created/initialized. – akash Mar 27 '14 at 08:35
  • hum... now I'm wondering about the difference between final and immutable. Need to think about it. Actually my concern is not about not changing a value after init, but safely returning values to a caller and making the caller unable to change the original values (allowing the caller to change the copies returned is okay). – mins Mar 27 '14 at 08:59
1

We come across these situations, in case we want to return wrapper class objects. Simple solution for this would be to return map as follow:

private void parentFunction() {
     Map<String,Integer> flagsForEventRule = new HashMap<>();
     // call the method inside which you want to set these parameters
     sample(flagsForEventRule);
     System.out.println(flagsForEventRule.get("pathsMatched"));
}

private void sample(Map<String,Boolean> flagsForEventRule) {
    // you can set the values in map like this
    flagsForEventRule.put("pathsMatched", 1);
    flagsForEventRule.put("shouldCreateRule", 2);
}
Amar Magar
  • 840
  • 1
  • 11
  • 15
0

1) When Java encounters int[], does it actually understand it as Integer[], I mean array can only hold references, not primitives ?

This is 2 different things,

  1. int[] is a standard primitives array,
  2. Integer[] is an array of Objects - meaning array of pointers to Integer Objects.

When it comes to return two immutable integers from a function, are those two ways equivalent?

  1. int is always mutable
  2. Integer is immutable

So in this case if you want to work with immutable objects, you need to use Integer, but then again you can always change the pointer in your array, and that way you'll lose consistency.

What is the standard practice to return two immutable integers?

I would look at apache common ImmutablePair()

mavarazy
  • 7,562
  • 1
  • 34
  • 60