I'm in the process of porting some C++ code to Java.
Here's a snippet of my code:
class Foo{
...
private class Bar
{
public byte[] data;
public int len;
Bar() {
data = new byte[256];
len = 0;
}
}
...
private Bar[] myArray = new Bar[10];
I want to have an array of 10 objects. But when I want to use the array further in my code, I notice that all 10 members are 'null'.
As a workaround I can solve it with a for-loop in the constructor of the primary class:
Foo() {
for( int i=0; i<myArray.length; i++ )
myArray[i] = new Bar();
}
Is there a better way to call the 10 constructors at once, without the need for a for-loop?
If you were prepared to use an implementation of the List interface, you could do the following:
List<Bar> myArray = new ArrayList<>(Collections.nCopies(10, new Bar());
/* ^ number of copies */
But this is not possible with primitive arrays ([n] style)
You'll need some for-loop equivalent in order for each index of the array to refer to a unique object.
For example:
IntStream.range(0,myArray.length).forEach(i->myArray[i] = new Bar());
Otherwise, if you don't mind all indices of the array to refer to the same object:
Arrays.fill(myArray, new Bar());
Related
Just out of curiosity, based on that code is there a way to that instead of
int [][]d = { obj[0].ar , obj[1].ar , obj[2].ar };
can be written under a for like this
for(int i=0;i<obj.ar.length;i++)
or to just combine all arrays of obj[].ar using obj.length in one 2 dimenstional array?
public class Main
{
public static void main(String[] args)
{
int nb = 3;
arr[] obj = new arr[nb];
for(int i=0;i<obj.length;i++)
{
obj[i] = new arr(i+2);
}
int [][]d = { obj[0].ar , obj[1].ar , obj[2].ar };
for(int i=0;i<d.length;i++)
{
for(int j=0;j<d[i].length;j++)
System.out.print(d[i][j]+"\t");
System.out.println();
}
}
}
class arr
{
int []ar;
arr(int nb)
{
ar = new int[nb];
for(int i=0;i<ar.length;i++)
ar[i]=i;
}
}
Java arrays must always have a determined size upon creation.
Notice you are always setting nb in the calls to new arrays, or by using the {} instantiator which will count the number of objects statically.
What you are asking for is probably what ArrayList is meant to achieve. It will grow as you go, while having an array implementation behind the scenes. If the contents cannot fit in the array, a new - larger - array is created to fit them all. You won't notice this while using it though.
ArrayList<ArrayList<Integer>> obj = new ArrayList<>();
obj.add(new ArrayList<>());
obj.add(new ArrayList<>());
obj.add(new ArrayList<>());
// There are now three empty lists, in the main list.
Since java 9, you can use some extra helper methods:
List<List<Integer>> obj = List.of(
List.of(1,2,3),
List.of(2,3,4)
);
If you want, you can implement you own ArrayList class, it's not that hard!
I'm trying to create two different types of Arrays within one ArrayList. Set up constructors accordingly (I think), but when it comes to instantiating them I get an error message "arr cannot be resolved". I'm slowly but surely going round the bend. How do I get the ArrayList to accept a simple array with doubles? (It also has to accept other types so it's not just a question of changing the ArrayList itself).Here's the code for the constructors & main ArrayList:
class NumList implements Num
{
private ArrayList<Num> n1;
public NumList( NumDouble[] doubleArray )
{
n1 = new ArrayList<Num>();
for( NumDouble d : doubleArray )
n1.add( d );
}
public NumList(NumFloat[] floatArray )
{
n1 = new ArrayList<Num>();
for( NumFloat d : floatArray )
n1.add( d );
}
// methods of Num interface
}
And my test class looks like this -
import java.util.ArrayList;
public class Demo extends NumList {
public Demo(NumDouble[] doubleArray) {
//suggested automatically to add super here
super(doubleArray);
double[] arr = {(1.1), (2.2), (3.3), (4.4)};
ArrayList<Num> n1 = new ArrayList<Num>(arr);
}
public static void main (String [] args){
arr.sqrt();
System.out.println("The numbers sq are "+ arr [0]);
}
}
The NumList class has just three methods including sort. I have tried wildcards as well as
It's probably something really easy ... any help appreciated.
Your ArrayList holds object of type Num, but you are trying to insert plain ol' doubles into it
double[] arr = {(1.1), (2.2), (3.3), (4.4)};
ArrayList<Num> n1 = new ArrayList<Num>(arr);
double does not inherit from Num and so cannot be placed in an ArrayList<Num>. Also, no ArrayList constructor takes an array as a parameter, you have to convert your array to a collection with Arrays.asList(array). You would have to do something like this
NumDouble[] arr = {new NumDouble(1.1), new NumDouble(2.2), new NumDouble(3.3), new NumDouble(4.4)};
ArrayList<Num> n1 = new ArrayList<Num>(Arrays.asList(arr));
I'm trying to create objects within a for loop at runtime. Here is the (incorrect) code:
for(int i=1;i<max;i++){
Object object(i);
}
I'd like it to create max number of Object objects with names object1, object2, etc. Is there any way to do this? I have been unable to find anything elsewhere online. Thanks for your help!
You want to use a data structure to store a sequence of objects. For example, an array could do this:
Fruit banana[] = new Fruit[10];
for (int i = 0; i < 10; i++){
banana[i] = new Fruit();
}
This creates 10 objects of type Fruit in the banana array, I can access them by calling banana[0] through banana[9]
You could use an array to create multiple objects.
public void method(int max) {
Object[] object = new Object[max];
for (int i = 0; i < max; i++) {
object[i] = new Object();
}
}
Integer[] lastExchange = new Integer[nColors];
Integer[] exchangeToAdd = new Integer[nColors];
lastExchange = getValue();
exchangeToAdd = getValue();
exchanges.add(exchangeToAdd);
Integer[] newExchange = new Integer[nColors];
while (true) {
newExchange = getValue(lastExchange);
Integer[] exchangeToAddForLoop = new Integer[nColors];
for (int i=0; i<nColors; i++) {
lastExchange[i] = newExchange[i];
exchangeToAddForLoop[i] = newExchange[i];
}
exchanges.add(exchangeToAddForLoop);
}
ADDED
What I am trying to do with this code? I need to populate (fill in) the list called exchanges. The first element of the list is lastExchange. My problem with the code is that I always need to create two duplicates of an variable (it is why I think that the code is not elegant but I cannot find a better solution). For example, in the very beginning I create lastExchange and then I create exchangeToAdd (that has the same value as lastExchange). The same happens in the loop. I create lastExchange and then I create exchangeToAddForLoop. I do so because I cannot add lastExchange to the list because it will be modified latter.
ADDED 2
Here is my problem. I have the code like that:
Integer[] e = getValue();
Integer[] e1 = getValue(); // <-- I do not like that.
exchanges.add(e1); // <-- I do not like that.
while (true) {
Integer[] e_new = getValue(e);
Integer[] e2 = new Integer[nColors]; // <-- I do not like that.
for (int i=0; i<nColors; i++) {
e[i] = e_new[i];
e2[i] = e_new[i]; // <-- I do not like that.
}
exchanges.add(e2); // <-- I do not like that.
}
and I need to calculate e1 and e2 additionally to the calculation of e.
This is inelegant code in at least two ways:
Most of your local variables are being assigned values which are then immediately overwritten
Your newExchange variable could be declared more deeply nested.
So without changing any behaviour, here's a nicer version:
Integer[] lastExchange = getValue();
Integer[] exchangeToAdd = getValue();
exchanges.add(exchangeToAdd);
while (true) {
Integer[] newExchange = getValue(lastExchange);
Integer[] exchangeToAddForLoop = new Integer[nColors];
for (int i=0; i<nColors; i++) {
lastExchange[i] = newExchange[i];
exchangeToAddForLoop[i] = newExchange[i];
}
exchanges.add(exchangeToAddForLoop);
}
Next we come to the problem that you haven't told us what any of this code is meant to be doing, nor what you mean by "the duplicate local variable problem". Oh, and as pointed out in the comments, your loop never terminates.
Without discussing your code, when you have duplicate variable errors, you can always use {}.
This does not compile
int a=0;
a++;
int a=0;
a++;
this does:
{
int a=0;
a++;
}
{
int a=0;
a++;
}
#Jon's simplification is the safest, however I suspect it can be simplified further.
exchanges.add(getValue());
while (true) { // forever??
// do you need null values or can you use int[]
int[] newExchange = getValue(exchanges.get(exchanges.size()-1);
// do you need to add a copy, if not then clone() can be dropped.
exchanges.add(newExchange.clone());
}
I'm in need of help right now. I need to convert 2 dimensional array of numbers to a one dimensional array in Java. Can anyone help me?
Do you mean something like this?
import java.util.*;
public class Test {
public static void main(String[] args) {
String[][] data = new String[][] {
{ "Foo", "Bar" },
{ "A", "B" }
};
String[] flattened = flatten(data);
for (String x : flattened) {
System.out.println(x);
}
}
public static <T> T[] flatten(T[][] source) {
int size = 0;
for (int i=0; i < source.length; i++) {
size += source[i].length;
}
// Use the first subarray to create the new big one
T[] ret = Arrays.copyOf(source[0], size);
int index = source[0].length;
for (int i=1; i < source.length; i++) {
System.arraycopy(source[i], 0, ret, index, source[i].length);
index += source[i].length;
}
return ret;
}
}
If you want it for primitive types, you'll have to write an overload for each primitive type, but you can use new int[size] instead of Arrays.copyOf at that point.
A Java 8 solution could look something like this:
import java.util.stream.Stream;
public class ArrayConverter {
public static String[] flatten(String[][] array) {
// Create a stream of the given array
return Stream.of(array)
// Map each of its elements to a stream (thus creating a
// one-dim-array inside the stream, so to say)
.flatMap(Stream::of)
// Retrieve the stream as array, explicitly calling String to
// keep the type
.toArray(size -> new String[size]);
}
}
I consciously left out generic types in this example since it makes the Array Initialization somewhat confusing. Let me know if you need it tho.
Notably; if you want to use this conversion for Arrays of primitive types you should use the corresponding flat Methods of the Stream Class.
E.g. if you're using int-Arrays use:
Stream.flatMapToInt(...)
to retrieve an IntStream with actual primitive int-Values thus dodging autoboxing into Integer Objects.
JavaDoc of Stream for reference