I was reading this and wondered whether there is a particular reason for having methods which fill a pre-existing array or object with data, rather than returning an instance of the object or data.
In some cases, such as graphics it allows an object to be re-used only rewriting the primitives without allocating another object on each call.
Are there any other benefits which I am not considering?
I was reading this and wondered whether there is a particular reason
for having methods which fill a pre-existing array or object with
data, rather than returning an instance of the object or data.
These are two alternative ways.
Providing a object to be populated as parameter of a method has some advantages when (there are of course others):
1) you want to provide to the method an object with a state defined by the client and not in a generic or pristine state defined in the invoked method.
Without passing an instance of it as parameter, you cannot do it.
2) you want to spare memory consumption. If you have already an object to pass it as parameter, why creating a new one in the invoked method ?
3) you have multiple objects to value in the method but a method can only return a single object.
Imagine you want to populate 3 lists in the implementation.
For example you could invoke poupulateList(myList, myOtherList, myAgainOtherList);
with this implementation :
public void populateList(List<String> list, List<String> myOtherList, List<String> myAgainOtherList){
....
}
Without passed the objects as parameters you are forced to introduce a custom class that contains all these objects and to define it as the returned type of the method.
Consider the following simplistic method, which fills an integer array with a few numbers:
public void fillArray(int[] array) {
array[0] = 0;
array[1] = 1;
array[2] = 2;
}
// now use it
int[] array = new array[3];
fillArray(array);
When the method fillArray() populates the array with some values, it is addressing the actual array passed in by the caller. The caller retains the reference to his array, and hence there is no need to pass a reference back to the data. Note that we could change the signature of fillArray() to int[], and return a reference to the array, but functionally speaking it would not make much difference.
Where returning an int[] might make sense is if we wanted to make a method which allocated space for an array and then returned the result, e.g.
public int[] getArray() {
int[] array = new int[3];
array[0] = 0;
array[1] = 1;
array[2] = 2;
return array;
}
In this case, the caller doesn't have/want any exposure to workings of the array, he only wants the final product. Therefore, returning a reference to the array makes sense, without which the caller could not use the data generated by the method.
I understand why you are wondering. The design of MemoryInfo and getMemoryInfo() allow you to create as many MemoryInfo objects as you want, but if they were all to be correct, they should all hold the same data, so it would not really make sense to do. A clearer design would give you four getters that would return the four values.
I suppose that one reason for the chosen design is efficiency: it allows you to pass the same object to the method on every call, and it gives you all the information in one call instead of four. I am guessing here, though.
In general there are more things to consider when choosing one design over another. For example, if a method is to give you some information about a person, I would find it natural to pass a person object in for the method to modify rather than the method returning a new person object representing the same person every time called. Or at least it should give you the same object each time, only a new one when you inquire about a new person.
I have numbers[x][y] and int pm2 = 0;. Is there a way to pass on this Mult-Array onto public static boolean checkNumber(int[] list, int num)? <- the parameters has to be used this way.
I invoked checkNumber(numbers[x][y], pm2);
I need to use the checkNumber method to check if a number has already been entered and returns true if the number is present and false if number is absent.
I am allowed to use multiple methods thought so I did have an idea of doing numbers[x][0] , numbers[x][1] etc, etc and invoking them into multiple checkNumber() methods. I was just wondering if there's a shorter way.
You have single dimensional array as parameter.
So you have to pass one at a time probably in loop.
I was just wondering if there's a shorter way.
No there isn't. The Java language doesn't support any kind of array "slicing", and you can't subvert the type system to allow you to refer use an array with a different type to what it really has.
You need to implement your idea of iterating the int[] component array of the int[][], passing each one to checkNumber(int[], int). Something like this:
for (int[] subarray : numbers) {
checkNumbers(subarray, pm2);
}
I have to write a method that traverses a huge object's contents which are spread across machines and need to return this:
starting index in the object's struct(ex: if it has 10 pieces/blocks I can return piece/block 3-7)
offset within the first piece
list/array of pair < id of each piece, size of each piece > (not map - I've been clearly told not to use Map or Map.Entry)
Quoting exact words, I'm required to return fully-allocated array corresponding to the block range.
Thought #1: The starting index and offset are to be returned once, the option to create a class with
index
offset
id
size
and returning an array of this will be providing redundant information plus, adding 8 bytes every entry is huge waste of memory.
Thought #2: I could create a data class with (id and size) and return another class with array of this smaller class + index & offset, but in this case the existence of my data class will be just to contain values which doesn't seem v. prudent.
Thought #3:I've heard multiple times that people resort to arrays when need to return pairs. I don't know how to do that?
You have to create, basically, a data structure. There is a single way to do that in Java: use classes.
Your first thought is wrong: you must return a single index, and a single offset, and multiple pairs. It's thus wrong to put all the fields in a single class, since the cardinality of the fields is not the same. In particular, if there is 0 pair to return, you would be very embarrassed.
Your second thought maps exactly to what you must return. Except I would use a collection (List or Set) instead of an array:
public class Result {
private int index;
private int offset;
private Set<Piece> pieces;
...
}
public class Piece {
private String id;
private int size;
...
}
Why use a collection rather than a Piece[] array: because there's a good chance that you don't know the number of pieces before the traversal. Because a List or Set has many useful methods that an array doesn't have. Because a Set<Piece> clearly says that there are no duplicate elements, which is not the case with an array of Piece.
The third thought consists in using an Object[] containing 2 elements (or an int[] of two elements, if both the ID and the size are of type int, for example), to hold the information about a Piece. But that is ugly and unreadable: it's not obvious at all what the array contains, in which order, and what their type is. And you can't add any useful method like you could with a Piece class.
Java is an OO language. Use classes and objects. Use encapsulation.
In an interview I was being asked by two questions that are..
When does practically we require the use of vector..?
As per my analysis synchronization is the main reason but they were intrested to know that apart from synchronization what are the other practical reasons that we may prefer the use of vector.
Please advise that apart from synchronization what are the other various reason that we will choose vector legacy collection..!
One difference I can think of is Vector supports Enumeration.You can get create Enumeration easily by calling
Enumeration enums = v.elements();
But in case of ArrayList,you need to do like this:
Enumeration enums = Collections.enumeration(arrayList);
Vectors are used in the variable length argument in java.because Vector can automatically expand based on the argument passed to it.
for example
public int sum(int i...)
{
int sum=0;
for(int s:i)
{
sum=sum+s;
}
return sum;
}
in this method I have passed i as an variable length argument no matter how many integer the user will pass to this method ,this method will return the sum based on the user arguments..
so vector provides this facility to the user.
this is where vectors are implemented.Internally the variable length arguments uses Vector to
store the Data.
Okay, here is what I want to do:
I want to implement a crossover method for arrays.
It is supposed to take 2 arrays of same size and return two new arrays that are a kind of mix of the two input arrays.
as in [a,a,a,a] [b,b,b,b] ------> [a,a,b,b] [b,b,a,a].
Now I wonder what would be the suggested way to do that in Java, since I cannot return more than one value.
My ideas are:
- returning a Collection(or array) containing both new arrays.
I dont really like that one because it think would result in a harder to understand code.
- avoiding the need to return two results by calling the method for each case but only getting one of the results each time.
I dont like that one either, because there would be no natural order about which solution should be returned. This would need to be specified, though resulting in harder to understand code.
Plus, this will work only for this basic case, but I will want to shuffle the array before the crossover and reverse that afterwards. I cannot do the shuffling isolated from the crossover since I wont want to actually do the operation, instead I want to use the information about the permutation while doing the crossover, which will be a more efficient way I think.
My question is not about the algorithm itself, but about the way to put in in a method(concerning input and output) in Java
Following a suggestion from Bruce Eckel's book Thinking in Java, in my Java projects I frequently include some utility classes for wrapping groups of two or three objects. They are trivial and handy, specially for methods that must return several objects. For example:
public class Pair<TA,TB> {
public final TA a;
public final TB b;
/**
* factory method
*/
public static <TA,TB> Pair<TA,TB> createPair(TA a,TB b ){
return new Pair<TA,TB>(a,b);
}
/**
* private constructor - use instead factory method
*/
private Pair(final TA a, final TB b) {
this.a = a;
this.b = b;
}
public String toString() {
return "(" + a + ", " + b + ")";
}
}
Read the last section of this article:
http://www.yoda.arachsys.com/java/passing.html
To quote:
This is the real reason why pass by
reference is used in many cases - it
allows a method to effectively have
many return values. Java doesn't allow
multiple "real" return values, and it
doesn't allow pass by reference
semantics which would be used in other
single-return-value languages.
However, here are some techniques to
work around this:
If any of your return values are status codes that indicate success or
failure of the method, eliminate them
immediately. Replace them with
exception handling that throws an
exception if the method does not
complete successfully. The exception
is a more standard way of handling
error conditions, can be more
expressive, and eliminates one of your
return values.
Find related groups of return values, and encapsulate them into
objects that contain each piece of
information as fields. The classes for
these objects can be expanded to
encapsulate their behavior later, to
further improve the design of the
code. Each set of related return
values that you encapsulate into an
object removes return values from the
method by increasing the level of
abstraction of the method's interface.
For instance, instead of passing
co-ordinates X and Y by reference to
allow them to be returned, create a
mutable Point class, pass an object
reference by value, and update the
object's values within the method.
As a bonus, this section was updated by Jon Skeet :)
If it is reasonable for the caller to know the size of the returned arrays ahead of time, you could pass them into the method:
public void foo(Object[] inOne, Object[] inTwo, Object[] outOne, Object[] outTwo) {
//etc.
}
That being said, 90+% of the time multiple return values out of a method are hiding a better design. My solution would be to make the transformation inside an object:
public class ArrayMixer {
private Object[] one;
private Object[] two;
public ArrayMixer(Object[] first, Object[] second) {
//Mix the arrays in the constructor and assign to one and two.
}
public Object[] getOne() { return one; }
public Object[] getTwo() { return two; }
}
I suspect that in your real use case that class and array one and array two can get better names.
Since the specification of your method is that it takes two input arrays and produces output arrays, I agree with you that the method should return both arrays at the same time.
I think that the most natural choice of return value is an int[][] of length 2 (substitute int with whatever type you are using). I don't see any reason it should make the code harder to understand, especially if you specify what the contents of the return value will be.
Edit: in response to your comment, I understand that you have considered this and I am saying that despite your stylistic objections, I don't believe there is a strictly "better" alternative ("better" here being loosely defined in the question).
An alternative approach, largely equivalent to this one, would be to define an object that wraps the two arrays. This has the small distinction of being able to refer to them by names rather than array indices.
The best way to do it would be to do
public void doStuff(int[] array1, int[] array2) {
// Put code here
}
Since Java arrays in Java pass the reference, any modifications made to the arrays will be made to the array itself. This has several caveats
If you are setting it to null you must use a different way (such as encapsulating it in an object)
If you are initializing the array (in the method), you must use a different way
You would use this in the format:
// other method
int[] array1 = new int[20]; // the arrays can be whatever size
int[] array2 = new int[20];
doStuff(array1,array2);
// do whatever you need to with the arrays
Edit: This makes the assumption that it is okay to make changes to the input arrays.
If it isn't, then an object (such as in leonbloy's answer is definitely what is called for).
You strictly cannot return more then one value (think object or primitive) in Java. Maybe you could return an instance of a specific "Result" object which has the two arrays as properties?
You could pass the output arrays as parameters to the method. This may give you more control over memory allocation for the arrays too.
The cleanest and easiest to understand way would be to create a container bean that contains two arrays, and return the container from the method. I'd probably also pass in the container into the method, to keep it symmetric.
The most memory efficient way, assuming both arrays are the same length, would be to pass a multidimensional array - Object[2][n] - where n is the length of the arrays.
If you're really against the arbitrary ordering that comes from a 2d array or a collection, perhaps consider making an inner class that reflects the logic of what you're doing. You could simply define a class that holds two arrays and you could have your method return that, with names and function that reflect the logic of exactly what you're doing.
A simple solution to the above problem is to return as Map.The trick of this question is how you will define the keys to identify the objects, let say there are two
input arrays [a,a,a,a] [b,b,b,b] and two outputs arrays [a,a,b,b] [b,b,a,a]
For that you can use String variable as a key just to identify objects because String variable is immutable, so they can be used as keys.
And as example
Map<String,String[]> method(String[] x,String[] y){
do your stuff..........
Hashmap<String,String[]> map =new HashMap<String,String[]>();
map.put("Object2",[b,b,a,a]);
return map;
}