Java 8 - best way converting array elements - java

Starting with Java 8 so need a bit of time to get used to it. It's a classical problem, I've an array of objects that I want to transform.
Before Java8 the ideal code would be (no null pointers):
P[] outputArray = new P[inputArray.length];
for (int i =0; i< inputArray.length; i++ )
{
outputArray [i] = inputArray[i].transformToP();
}
What is the best version in Java8 ?

Using the Stream API it's quite simple:
P[] outputArray = Arrays.stream(inputArray).map(e -> e.transformToP()).toArray(P[]::new);
Also method reference can be used (suppose that I is the type of input elements):
P[] outputArray = Arrays.stream(inputArray).map(I::transformToP).toArray(P[]::new);
Note that you may have problems if transformToP() method throws checked exceptions. In this case convert them to unchecked ones or consult this question.

Using a stream over an array is a fine technique as described in Tagir Valeev's answer. However, don't forget about Arrays.setAll. This is a handy shortcut for setting all the elements of an array based on index. To transform an array to a new array by some function, you could do this:
P[] outputArray = new P[inputArray.length];
Arrays.setAll(outputArray, i -> inputArray[i].transform());
You don't have to copy it into a new array. If you want to transform the array in-place, you could do this:
Arrays.setAll(array, i -> array[i].transform());
There is also a parallel variation parallelSetAll.
Under the covers this is just an IntStream.range over the indexes of the input array, but it's sometimes darned convenient for quick one-liners.

Related

How get int[] array from column in rows of ResultSet?

I am using the following way to put int values from a ResultSet into an int array. This seems very innefficient but I can't figure out how to get an array of primitive int's where I don't know the size beforehand.
List<Integer> ints = ArrayList<Integer>();
while ( results.next ) ints.add( results.getInt( "id" );
int[] intsArray = new int[ ints.size() ];
for ( int i = 0; i < ints.length; i++ ) int[ i ] = ints.get( i ); //auto-boxes here
I need these to be a primitive array as that's what a method requires.
If you don't know the number of values read from the result set you really can't avoid using a list.
But you can avoid using a List<Integer> if you have a list class which can store primitive int values like for example TIntList of the trove project.
In the end you should really measure the performance impact of using intermediate Integer objects before spending too much energy on that question.
Convert ArrayList to array
You would have to guess an initial size and then resize the array as you fill its last element, repeating as needed as you go through your result set.
This behavior is exactly what ArrayList already gives you. But already debugged. ;-)
So just use ArrayList<Integer>. Convert to an array at the end.
You might think to use Collection::toArray. But that utility can only return an array of objects, not primitives.
See this Question, for several good ways to convert to array of primitives.
My choice would be calling on Google Guava. While adding Guava for this one purpose might be overkill, Guava is so useful so often that I add the library by default to most any new Java project.
List< Integer > list = ... ;
int[] values = Ints.toArray( list ) ;
If your deployment environment were extremely tight on memory, or if you had a very large number of elements, or if you were doing this operation so often as to impact performance, only then would I resort to filling-and-resizing an array int manually yourself.

How to add an element at the end of an array?

I want to know how to add or append a new element to the end of an array. Is any simple way to add the element at the end? I know how to use a StringBuffer but I don't know how to use it to add an element in an array. I prefer it without an ArrayList or list. I wonder if the StringBuffer will work on integers.
You can not add an element to an array, since arrays, in Java, are fixed-length. However, you could build a new array from the existing one using Arrays.copyOf(array, size) :
public static void main(String[] args) {
int[] array = new int[] {1, 2, 3};
System.out.println(Arrays.toString(array));
array = Arrays.copyOf(array, array.length + 1); //create new array from old array and allocate one more element
array[array.length - 1] = 4;
System.out.println(Arrays.toString(array));
}
I would still recommend to drop working with an array and use a List.
Arrays in Java have a fixed length that cannot be changed. So Java provides classes that allow you to maintain lists of variable length.
Generally, there is the List<T> interface, which represents a list of instances of the class T. The easiest and most widely used implementation is the ArrayList. Here is an example:
List<String> words = new ArrayList<String>();
words.add("Hello");
words.add("World");
words.add("!");
List.add() simply appends an element to the list and you can get the size of a list using List.size().
To clarify the terminology right: arrays are fixed length structures (and the length of an existing cannot be altered) the expression add at the end is meaningless (by itself).
What you can do is create a new array one element larger and fill in the new element in the last slot:
public static int[] append(int[] array, int value) {
int[] result = Arrays.copyOf(array, array.length + 1);
result[result.length - 1] = value;
return result;
}
This quickly gets inefficient, as each time append is called a new array is created and the old array contents is copied over.
One way to drastically reduce the overhead is to create a larger array and keep track of up to which index it is actually filled. Adding an element becomes as simple a filling the next index and incrementing the index. If the array fills up completely, a new array is created with more free space.
And guess what ArrayList does: exactly that. So when a dynamically sized array is needed, ArrayList is a good choice. Don't reinvent the wheel.
The OP says, for unknown reasons, "I prefer it without an arraylist or list."
If the type you are referring to is a primitive (you mention integers, but you don't say if you mean int or Integer), then you can use one of the NIO Buffer classes like java.nio.IntBuffer. These act a lot like StringBuffer does - they act as buffers for a list of the primitive type (buffers exist for all the primitives but not for Objects), and you can wrap a buffer around an array and/or extract an array from a buffer.
Note that the javadocs say, "The capacity of a buffer is never negative and never changes." It's still just a wrapper around an array, but one that's nicer to work with. The only way to effectively expand a buffer is to allocate() a larger one and use put() to dump the old buffer into the new one.
If it's not a primitive, you should probably just use List, or come up with a compelling reason why you can't or won't, and maybe somebody will help you work around it.
As many others pointed out if you are trying to add a new element at the end of list then something like, array[array.length-1]=x; should do. But this will replace the existing element.
For something like continuous addition to the array. You can keep track of the index and go on adding elements till you reach end and have the function that does the addition return you the next index, which in turn will tell you how many more elements can fit in the array.
Of course in both the cases the size of array will be predefined. Vector can be your other option since you do not want arraylist, which will allow you all the same features and functions and additionally will take care of incrementing the size.
Coming to the part where you want StringBuffer to array. I believe what you are looking for is the getChars(int srcBegin, int srcEnd,char[] dst,int dstBegin) method. Look into it that might solve your doubts. Again I would like to point out that after managing to get an array out of it, you can still only replace the last existing element(character in this case).
one-liner with streams
Stream.concat(Arrays.stream( array ), Stream.of( newElement )).toArray();

Is there a quick way to create an array of return codes from another array?

Suppose I have an array of objects from the MyClass class:
MyClass myClassArray[] = {
new MyClass(0, 1),
new MyClass(2, 3),
new MyClass(4, 5),
new MyClass(6, 7)
};
Here, the MyClass constructor fills in two fields, which we shall call field1 and field2. Suppose now that I want to fill in an array containing the value of field1 from each object in myClassArray (so the array will contain the values 0, 2, 4, 6). The following does not work:
field1Array = myClassArray.getField1();
Is there a quick 1-line way to fill in the new array using return codes from methods belonging to objects in the original array? Obviously, I can do this using a for loop, but I'd rather make use of the features of the language, if they exist.
You will need to loop unless you are using Java 8+ which adds lambda expressions to the language, in which case you can map your array to a new array:
int[] field1Array = Arrays
.stream(myClassArray)
.mapToInt(MyClass::getField1)
.toArray();
This is admittedly a theoretical answer since Java 8 will not be officially released until Q1 next year.
Currently there are no other language features than a plain old and simple for loop.
With Java 8 there may be lambda expressions and perhaps some helper method for Collection which will do what you want. But Java 8 is not yet released.
No, as far as I know, in Java, there is no way to call a method on every element of the array, apart from using a loop.
int[] field1 = new int[myClassArray.size()];
for(int i = 0; i < myClassArray.size(); i++){
field1[i] = myClassArray[i].getField1();
}
Your approach has to use a loop (while, here for), because you can't run through an array without one. Sure you can handle each element of the array one by one. But this would be a nightmare for a fair size of elements in the array.

participal Eigenvalues Java (JAMA)

I just ported my code from MATLAB to Java, and I need the eigen decomposition of a matrix, specifically I only need the first k values not the full decomposition.
However in JAMA, the eigen-decomposition class computes the full eigen decomposition. I tried to modify it, but it throws some errors. Is there another similar library?
In MATLAB, the function in question is eigs(k,A)
So it's just returning the array of all the eigenvalues. You want to return an array with just the first k values of the array. There are many ways to do this in Java. One is to convert the array to an ArrayList, get a subList of that list, and convert back to an array.
double[] mySubArray = new double[k];
for (int i=0; i < k; i++) {
subArray[i] = myFullArray[i];
}
By the way, this is the library he is referring to: http://math.nist.gov/javanumerics/jama/doc/
In the case you cannot find any existing codes, I guess you should refer to this thesis or maybe this paper.
Maybe you can try another package named EigenDecomposition in http://commons.apache.org/proper/commons-math/javadocs/api-3.6/org/apache/commons/math3/linear/EigenDecomposition.html, there are some methods like getImagEigenvalue(int i), you can get the i-th eigenvalue by this.

Conversion from Vector<double[]> to double[][]

How can I convert Vector<double[]> to double[][] in java ?
You can convert a Vector to an array by Vector.toArray():
double[][] array = vector.toArray(new double[0][]);
This maybe slightly faster then for loop, because Vector can utilize System.arraycopy() on its internal array.
This will do it:
double matrix[][] = new double[vector.size()][];
for (int i = 0; i < vector.size(); i++) {
matrix[i] = vector.get(i);
}
Note that this references the same double[] arrays as in your Vector<double[]>. So a change in that will be reflected in the new matrix[][]. If you don't want that then you'll have to create a new double[] for each iteration and copy the values from the old array to the new array.
Muhammed,
WhiteFang is correct... if you're looking for an "out of the box" solution then have a look at Apache's Commons Collections (http://commons.apache.org/collections/)
It's been over a year since I touched Java, but if I recall correctly, "commons" has converters for Vectors... as well as many, many, many other handy bits of kit.
And BTW: If using a Vector is your choice, and you don't have a good reason to NOT use an ArrayList, then use an ArrayList... It's slightly quicker. Except it's NOT threadsafe; whereas all Vectors methods are syncronised. Explanation here: http://skeletoncoder.blogspot.com/2006/09/java-tutorials-arraylist-or-vector.html.
Cheers. Keith.

Categories