Java-Hibernate from List of values to multidimensional double arrays - java

With the following snippet I am trying to build from a List returned from Hibernate a multidimensional array , double[][]:
The data list gets to makeSet, the makeSet tries to return a [][] double array. The optimal, is that I don't know how many arrays should I have. So I tried calling makeInnerSet but unless I create a new double[][] ix, iy in the code, the code does not iterate well.
Is there a way to know the columns of an array [][] ?
Perhaps is there another approach to the problem ?
It's mandatory to take back the scalar values of Hibernate and make them double[][] of what ever size. Any help ?
List data = qry.list();
double[][] inputData = makeSet(data);
public double[] makeInnerSet(List data, double[] ix, int col ){
int i = 0;
Iterator<?> itr1 = data.listIterator();
while (itr1.hasNext()) {
Object[] result = (Object[]) itr1.next();
if (result[col] != null) {
double res1 = (Double) result[col];
ix[i] = res1;
}else{
ix[i] = 0;
}
i++;
}
return ix;
}
public double[][] makeSet(List data){
Iterator<?> itr1 = data.listIterator();
double[] ix = new double[data.size()];
double[] iy = new double[data.size()];
double[][] x = { makeInnerSet(data, iy,0), makeInnerSet(data, ix,1) };
return x;
}
EDIT
Well making making the code :
double[][] x = {
makeInnerSet(data, new double[data.size()],0),
makeInnerSet(data, new double[data.size()],1)
};
Half-found my answer...seconds later...
I certainly now don't need the ix, iy. But how do I take the number of columns in the List ?

Assuming all arrays in the list have the same size (because otherwise makeinnerset would bomb ,too):
int columns = ((Object[])data.first()).size()
the code gets the first array and get its size which should be the same for all arrays.

Related

How to add element to that variable list like this "List<Object[]> listObject" in java?

I don't know how to add element if the type data in squareBracket is array.
If you want to add element in List then simply do:
listObject.add(new Object[]{});
Or if you want to add to Object array inside list then use (Which is quite a long root due to restrictive behavior of array data structure, Thats why ArrayList is alternative to achieve this. ):
#Test
public void testArray() {
List<Object[]> listObjects = new ArrayList<>();
listObjects.add(new Object[]{1,2});
addX( listObjects.get(0).length , listObjects.get(0) , 3);
listObjects.set(0,addX( listObjects.get(0).length , listObjects.get(0) , 3));
System.out.println(listObjects.get(0));
}
public Object[] addX(int n, Object arr[], Object x)
{
int i;
// create a new array of size n+1
Object newarr[] = new Object[n + 1];
// insert the elements from
// the old array into the new array
// insert all elements till n
// then insert x at n+1
for (i = 0; i < n; i++)
newarr[i] = arr[i];
newarr[n] = x;
return newarr;
}

Adding double values to array list from strings

I'm trying to covert an array of strings into an array of doubles.
I'm fairly familiar with ArrayList<>() , but i see there is in an example code give, double[].
example: list = ["1" , "2" , "3"]
desired return: number = [1 , 2 , 3]
public double[] ConversionNumber
{
double[] sequence = new double[list.size()];
for(String element:list){
double val = Double.parseDouble(element);
sequence.add(val)}
return sequence;
when i do this, i get an error in Bluej compiler: "cannot find symbol- method add(double).
What is a good way to solve this (i'm a beginner at Java).
thanks!
If list is an array, then list.size() would fail. I think we can assume it should be a List<String>. And you access an array by index. Also, I assume it should be an argument to your method. Next, Java convention for methods names is camelCase.
public double[] conversionNumber(List<String> list) {
double[] sequence = new double[list.size()];
int pos = 0;
for (String element : list) {
double val = Double.parseDouble(element);
sequence[pos++] = val; // <-- post-increment
}
return sequence;
}
Generally, if you're working with Collections, you work with collections the whole way. It's bad form to use Lists for one thing, but arrays for another. So it's advisable to do this with a List<Double> instead of a double[]
public List<Double> parseDoubles(List<String> strings) {
List<Double> doubles = new ArrayList<>(strings.size());
for(String string : strings) {
doubles.add(new Double(string));
}
return doubles;
}
Below code will work for your case:
java.util.List<String> list = java.util.Arrays.asList("1", "2", "3");
public double[] ConversionNumber() {
double[] sequence = new double[list.size()];
int i = 0;
for(String element:list){
double val = Double.parseDouble(element);
sequence[++i] = val;
}
return sequence;
}
The error happens because arrays dont have an 'add' method. You will want to do something like:
double[] sequence = new double[list.length];
for(int i = 0; i < list.length; i++){
sequence[i] = Double.parseDouble(list[i]);
}
If list is an actual List not a String[] as I assumed, you would do:
double[] sequence = new double[list.size()];
for(int i = 0; i < list.size(); i++){
sequence[i] = Double.parseDouble(list.get(i));
}
Change your code here
for(String element:list){
double val = Double.parseDouble(element);
sequence.add(val)
}
to this if your list is a List:
for(int i=0;i<list.size();i++){
double val = Double.parseDouble(list.get(i));
sequence[i]=val;
}
if your list is an Array, then change to this:
for(int i=0;i<list.length;i++){
double val = Double.parseDouble(list[i]);
sequence[i]=val;
}

Shuffle the Integer of the Object<Integer,String> in a List/ArrayList

List<Data> list = new ArrayList<Data>();
public class Data{
public int n;
public String p;
public Data(int N, String P) {
n = N;
p = P;
}
}
How can i shuffle the Integer of the Object: Data. So the String stays at the same position, and the Integer get's shuffled.
Loop through list and store the int of each Data object in a separate list. Shuffle this list using Collections.shuffle(...). Loop through this new shuffled list and set the n field of each corresponding member of list to the new random int found in the shuffled list.
Probably have to do it yourself:
for (int i = list.size(); i > 0; i--) {
int j = (int)(Math.random() * (i + 1));
int temp = list.get(i).n;
list.get(i).n = list.get(j).n;
list.get(j).n = temp;
}
The best you can do from java libraries is to first split it into two lists, one of ints and one of strings, then shuffle only the ints (using Collections.shuffle), then combine the two lists back into one list of Datas
You could use something like this:
List<Integer> ns = new ArrayList<Integer>(list.size());
for (Data data : list) {
ns.add(data.n);
}
Collections.shuffle(ns);
for (int i = 0; i < list.size(); i++) {
Data data = list.get(i);
int newN = ns.get(i);
data.n = newN;
}
Note that it's best practice to use accessors getN() and setN(int) and make Data.n private.

Java array issue

How would I go about creating an array of say 5 items and then after create an array for each item?. I know how to create an array of 5 items but the problem I have is creating an array for each one after. Im assuming I would need 5 arrays since there's 5 items.
int gas = 0;
int food = 0;
int clothes = 0;
int entertainment = 0;
int electricity = 0;
int[] budget = new int[4];
budget[0] = gas;
budget[1] = food;
budget[2] = clothes;
budget[3] = entertainment;
budget[4] = electricity;
thanks in advance
Instead of creating a 2-dimensional array holding types of amounts that are logically grouped together (I assume per month) it would be better to define a data-holder class so that you can access the amounts using their name instead of an error-prone index.
For example (minus the getters and setters):
public class Budget {
public int gas = 0;
public int food = 0;
public int clothes = 0;
public int entertainment = 0;
public int electricity = 0;
};
// ....
Budget[] months = new Budget[12];
budget[0].gas = gasCosts;
budget[0].food = foodCosts;
// etc
Are you saying you want to create a 2D array? Each element in the budget array is another array?
You'd use a loop.
int[] budget = new int[5]; //There are 5 elements to be stored in budget, not 4
for (int y = 0; y < 5; y++) {
budget[y] = new int[5];
}
Maybe you need a matrix.
int[][] budget = new int[4][4];
In the first index you keep the budget and in the second index the five (in the case above) budget items.
When you have a matrix [x][y] you have x+1 arrays each of wich with y+1 elements.
There are 5 elements in the array.
int[] budget = new int[5];
budget[0] = gas;
budget[1] = food;
budget[2] = clothes;
budget[3] = entertainment;
budget[4] = electricity;
You need 2-dimensional array, which is basically an array of array. The 2D array is declared by 2 pairs of []. In the following example, each budget have 10 details.
String[][] detail = new String[budget.length][10];
If I'm understanding you correctly, you want a 2d array that would be something like ...
int gas = 0;
int food = 1;
int clothes = 2;
int entertainment = 3;
int electricity = 4;
int maxEntries = 10;
int[][] myArray = new int[5][maxEntries];
This could be accessed via:
myArray[gas][entryNumber] = 6;
int value = myArray[gas][entryNumber];
But how inflexible this is? You have to know in advance how many entries there will be for each "category" or have code that checks a given array length when you're adding an item, creating an new array when you need a larger one (and copying the old data into it).
What you probably want at the very least is a ArrayList of ArrayLists:
ArrayList<ArrayList<Integer>> my2dArrayList =
new ArrayList<ArrayList<Integer>>();
...
my2dArrayList.get(gas).add(someValue);
int myValue = my2dArrayList.get(gas).get(index);
Or a HashMap of ArrayLists you could access via the names of your categories:
HashMap<String, ArrayList<Integer>> myMap =
new HashMap<String, ArrayList<Integer>>();
...
myMap.get("gas").add(someValue);
int myValue = myMap.get("gas").get(index);

How can I convert int[] to Integer[] in Java?

I have a large dataset of length 4 int[] and I want to count the number of times that each particular combination of 4 integers occurs. This is very similar to counting word frequencies in a document.
I want to create a Map<int[], double> that maps each int[] to a running count as the list is iterated over, but Map doesn't take primitive types.
So I made Map<Integer[], Double>.
My data is stored as an ArrayList<int[]>, so my loop should be something like:
ArrayList<int[]> data = ... // load a dataset`
Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();
for(int[] q : data) {
// **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
I'm not sure what code I need at the comment to make this work to convert an int[] to an Integer[]. Or maybe I'm fundamentally confused about the right way to do this.
Native Java 8 (one line)
With Java 8, int[] can be converted to Integer[] easily:
int[] data = {1,2,3,4,5,6,7,8,9,10};
// To boxed array
Integer[] what = Arrays.stream( data ).boxed().toArray( Integer[]::new );
Integer[] ever = IntStream.of( data ).boxed().toArray( Integer[]::new );
// To boxed list
List<Integer> you = Arrays.stream( data ).boxed().collect( Collectors.toList() );
List<Integer> like = IntStream.of( data ).boxed().collect( Collectors.toList() );
As others stated, Integer[] is usually not a good map key.
But as far as conversion goes, we now have a relatively clean and native code.
If you want to convert an int[] to an Integer[], there isn't an automated way to do it in the JDK. However, you can do something like this:
int[] oldArray;
... // Here you would assign and fill oldArray
Integer[] newArray = new Integer[oldArray.length];
int i = 0;
for (int value : oldArray) {
newArray[i++] = Integer.valueOf(value);
}
If you have access to the Apache lang library, then you can use the ArrayUtils.toObject(int[]) method like this:
Integer[] newArray = ArrayUtils.toObject(oldArray);
Convert int[] to Integer[]:
import java.util.Arrays;
...
int[] aint = {1,2,3,4,5,6,7,8,9,10};
Integer[] aInt = new Integer[aint.length];
Arrays.setAll(aInt, i -> aint[i]);
Using regular for-loop without external libraries:
Convert int[] to Integer[]:
int[] primitiveArray = {1, 2, 3, 4, 5};
Integer[] objectArray = new Integer[primitiveArray.length];
for(int ctr = 0; ctr < primitiveArray.length; ctr++) {
objectArray[ctr] = Integer.valueOf(primitiveArray[ctr]); // returns Integer value
}
Convert Integer[] to int[]:
Integer[] objectArray = {1, 2, 3, 4, 5};
int[] primitiveArray = new int[objectArray.length];
for(int ctr = 0; ctr < objectArray.length; ctr++) {
primitiveArray[ctr] = objectArray[ctr].intValue(); // returns int value
}
Presumably you want the key to the map to match on the value of the elements instead of the identity of the array. In that case you want some kind of object that defines equals and hashCode as you would expect. Easiest is to convert to a List<Integer>, either an ArrayList or better use Arrays.asList. Better than that you can introduce a class that represents the data (similar to java.awt.Rectangle but I recommend making the variables private final, and the class final too).
The proper solution is to use this class as a key in the map wrapping the actual int[].
public class IntArrayWrapper {
int[] data;
public IntArrayWrapper(int[] data) {
this.data = data;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
IntArrayWrapper that = (IntArrayWrapper) o;
if (!Arrays.equals(data, that.data))
return false;
return true;
}
#Override
public int hashCode() {
return data != null ? Arrays.hashCode(data) : 0;
}
}
And change your code like this:
Map<IntArrayWrapper, Double > freqs = new HashMap<IntArrayWrapper, Double>();
for (int[] data : datas) {
IntArrayWrapper wrapper = new IntArrayWrapper(data);
if (freqs.containsKey(wrapper)) {
freqs.put(wrapper, freqs.get(wrapper) + p);
}
freqs.put(wrapper, p);
}
Convert int[] to Integer[]
public static Integer[] toConvertInteger(int[] ids) {
Integer[] newArray = new Integer[ids.length];
for (int i = 0; i < ids.length; i++) {
newArray[i] = Integer.valueOf(ids[i]);
}
return newArray;
}
Convert Integer[] to int[]
public static int[] toint(Integer[] WrapperArray) {
int[] newArray = new int[WrapperArray.length];
for (int i = 0; i < WrapperArray.length; i++) {
newArray[i] = WrapperArray[i].intValue();
}
return newArray;
}
Rather than write your own code, you can use an IntBuffer to wrap the existing int[] without having to copy the data into an Integer array:
int[] a = {1, 2, 3, 4};
IntBuffer b = IntBuffer.wrap(a);
IntBuffer implements comparable, so you are able to use the code you already have written. Formally, maps compare keys such that a.equals(b) is used to say two keys are equal, so two IntBuffers with array 1,2,3 - even if the arrays are in different memory locations - are said to be equal and so will work for your frequency code.
ArrayList<int[]> data = ... // Load a dataset`
Map<IntBuffer, Double> frequencies = new HashMap<IntBuffer, Double>();
for(int[] a : data) {
IntBuffer q = IntBuffer.wrap(a);
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
This worked like a charm!
int[] mInt = new int[10];
Integer[] mInteger = new Integer[mInt.length];
List<Integer> wrapper = new AbstractList<Integer>() {
#Override
public int size() {
return mInt.length;
}
#Override
public Integer get(int i) {
return mInt[i];
}
};
wrapper.toArray(mInteger);
Though the below compiles, it throws a ArrayStoreException at runtime.
Converting an int[], to an Integer[]:
int[] old;
...
Integer[] arr = new Integer[old.length];
System.arraycopy(old, 0, arr, 0, old.length);
I must admit I was a bit surprised that this compiles, given System.arraycopy being lowlevel and everything, but it does. At least in Java 7.
You can convert the other way just as easily.
I am not sure why you need a Double in your map. In terms of what you're trying to do, you have an int[] and you just want counts of how many times each sequence occurs(?). Why would this require a Double anyway?
I would create a wrapper for the int array with a proper .equals and .hashCode methods to account for the fact that int[] object itself doesn't consider the data in its version of these methods.
public class IntArrayWrapper {
private int values[];
public IntArrayWrapper(int[] values) {
super();
this.values = values;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(values);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntArrayWrapper other = (IntArrayWrapper) obj;
if (!Arrays.equals(values, other.values))
return false;
return true;
}
}
And then use Google Guava's multiset, which is meant exactly for the purpose of counting occurrences, as long as the element type you put in it has proper .equals and .hashCode methods.
List<int[]> list = ...;
HashMultiset<IntArrayWrapper> multiset = HashMultiset.create();
for (int values[] : list) {
multiset.add(new IntArrayWrapper(values));
}
Then, to get the count for any particular combination:
int cnt = multiset.count(new IntArrayWrapper(new int[] { 0, 1, 2, 3 }));
Int is a primitive. Primitives can’t accept null and have default value. Hence, to accept Null you need to use wrapper class Integer.
Option 1:
int[] nos = { 1, 2, 3, 4, 5 };
Integer[] nosWrapped = Arrays.stream(nos)
.boxed()
.toArray(Integer[]::new);
nosWrapped[5] = null // can store null
Option 2:
You can use any data structure that use wrapper class Integer
int[] nos = { 1, 2, 3, 4, 5 };
List<Integer> = Arrays.asList(nos)
You don't need it. int[] is an object and can be used as a key inside a map.
Map<int[], Double> frequencies = new HashMap<int[], Double>();
is the proper definition of the frequencies map.
This was wrong :-). The proper solution is posted too :-).

Categories