Initializing an object in an array with a default value - java - java

Is there a way to define a default value for an object in array to be initialized with?
In the same way that primitive types are initialized when declaring an array of them:
int[] myIntArray = new int[5]; // we now have an array of 5 zeroes
char[] myCharArray = new char[2]; // an array in which all members are "\u0000"
etc.
I'd like to declare an array of objects of a type that I've defined, and have them automatically initialize in a similar fashion.
I suppose this would mean I'd like to run new myObject() for each index in the array (with the default constructor).
I haven't been able to find anything relevant online, the closest I got was to use Arrays.fill(myArray, new MyObject()) after initializing the array (which actually just creates one object and fills the array with pointers to it), or just using a loop to go over the array and initialize each cell.
thank you!
EDIT: I realized this is relevant not just to arrays, but for declaring objects in general and having them default to a value / initialize automatically.

The Java 8 way:
MyObject[] arr = Stream.generate(() -> new MyObject())
.limit(5)
.toArray(MyObject[]::new);
This will create an infinite Stream of objects produced by the supplier () -> new MyObject(), limit the stream to the total desired length, and collect it into an array.
If you wanted to set some properties on the object or something, you could have a more involved supplier:
() -> {
MyObject result = new MyObject();
result.setName("foo");
return result;
}

Do this so you can initialize the array when declaring it:
int[] myIntArray = {0, 0, 0,0,0};
char[] myCharArray = { 'x', 'p' };
you could of course do:
int[] myIntArray = new int[5];
and the in a for loop set all indexes to the initial value... but this can take a while if the array is bigger...
Edit:
for custom objects is the same just use an anonymous constructor in the init
Example:
public class SOFPointClass {
private int x;
private int y;
public SOFPointClass(int x, int y) {
this.x = x;
this.y = y;
}
// test
public static void main(String[] args) {
SOFPointClass[] pointsArray = { new SOFPointClass(0,0) , new SOFPointClass(1,1)};
}
}

I don't see a way that Java provides to do this.
My suggestion would be define a function to do it.
Object[] initialize(Class aClass, int number) throws IllegalAccessException, InstantiationException {
Object[] result = new Object[number];
for (int i = 0; i < number; ++i) {
result[i] = aClass.newInstance();
}
}
Then call it as Object[] arr = initialize(YourClass.class, 10)

In Java, the array is initialized with the default value of the type. For example, int default is 0. The default value for cells of an array of objects is null as the array cells only hold references to the memory slot contains the object itself. The default reference points to null. In order to fill it with another default value, you have to call Arrays.fill() as you mentioned.
Object[] arr=new Object[2];
Arrays.fill(arr, new Object());

As far as I know there is no way of doing what you want with just plain java (that is to say there may be an external library I don't know about).
I would take the hit and loop over the array. Something like this should work:
myObject[] array = new myObject[5];
for (int i = 0; i < array.length; i++) {
array[i] = new myObject();
}
You could also shorten this using lambdas, like Cardano mentioned in his answer.

Related

Can Java use user defined object as an index of 2D array key?

array[obj][obj] = 1;
I want to create 2D array whose index is user defined object. How to do this? or there is some other data structure available to do this?
No the Java Language Specification states that an array can only be accessed using an int. Though thanks to primitive type promotion, short, char and byte can be used as well as they get automatically converted to int.
To solve your problem: You can store an int index inside your object and then use that to access the array.
array[obj.getIndex()][obj.getIndex()] = 1;
If you cannot directly influence the code of the user defined object, force the user to implement an interface that requires the getIndex() method.
interface ArrayIndexable {
int getIndex();
}
Alternatively if you cannot force the user to implement the interface, then you can maintain some sort of index using a map that maps the object to an int.
int x = ...;
int y = ...;
int[][] array = new int[x][y];
Map<SomeClass, Integer> index = new HashMap<>();
for(int i = 0; i < Math.max(x, y); i++) {
SomeClass m = ...; // object associated with i
index.put(m, i);
}
SomeClass obj = ...;
// accessing the array
array[index.get(obj)][index.get(obj)] = 1;
In an array, the index can be only one of the following short, byte, char or int.
For your use case, you might want to use a HashMap, it is a collection of keys and corresponding values. Key can be any user defined object and value can also be any defined object.
A simple hashmap example where keys are of type String and values are of type Double.
HashMap hm = new HashMap();
// Put elements to the map
hm.put("Zara", new Double(3434.34));
hm.put("Mahnaz", new Double(123.22));
hm.put("Ayan", new Double(1378.00));
hm.put("Daisy", new Double(99.22));
hm.put("Qadir", new Double(-19.08));
No, it array indices can be only integer in java but there is a way to achieve this.
Associate array indices to object using hashmap, and for each value retrive the index value using object as a key and use it as index.
//This example will help you
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class Experiment {
public static void main(String[] args) {
int a[]=new int[10];
HashMap<Student,Integer>map=new HashMap<>();
for (int i = 0; i < 10; i++) {
map.put(new Student(),i);
a[i]=i;
}
ArrayList al=new ArrayList(map.keySet());
int x;
for (int i = 0; i < al.size(); i++) {
x=map.get(al.get(i));
System.out.print(a[x] + " " + " ");
}
}
}
class Student{
int a,b;
}
But do remember hashmap doesn't preserve the insertion order.
Please comment if you face any problem or accept if works.
You can go for treemap if you want insertion order.

Define an array of arbitrary dimension [duplicate]

I am trying to create an array of arrays of arrays etc..., except I don't know how many nested levels deep it needs to be until runtime.
Depending on the input, I might need either int[], int[][], int[][][][][][], or anything else. (For context, I am trying to construct an N-dimensional grid for a cellular automaton, where N is passed as a parameter.)
I don't have any code for you because I have no idea how to go about this; I suspect is not possible at all using just arrays. Any help, or alternative solutions, would be appreciated.
You could do this with an Object[], limiting its members to either Object[] or int[].
For example, here's an array that goes three levels deep in one part, and two levels deep in another:
Object[] myarray = new Object[] {
new Object[] { new int[] { 1, 2 },
new int[] { 3, 4 }},
new int[] { 5, 6 }
};
After you've created it, you may want to access members. In your case, you know the depth N up front, so you know at what depth to expect an Object[] and at what depth to expect an int[].
However, if you didn't know the depth, you could use reflection to determine whether a member is another Object[] level or a leaf int[].
if ( myarray[0] instanceof Object[] ) {
System.out.println("This should print true.");
}
EDIT:
Here's a sketch [untested so far, sorry] of a method that access a member of an array of known depth, given an array of indices. The m_root member can be an Object[] or an int[]. (You could relax this further to support scalars.)
public class Grid {
private int m_depth;
private Object m_root;
...
public int get( int ... indices ) {
assert( indices.length == m_depth );
Object level = m_root;
for ( int i = 0; i + 1 < m_depth; ++i ) {
level = ((Object[]) level)[ indices[i] ];
}
int[] row = (int[]) level;
return row[ indices[m_depth - 1] ];
}
}
This should be achievable using Object[], since arrays are objects:
int[] arr = {1,2,3};
int[] arr2 = {1,2,3};
int[] arr3 = {1,2,3};
int[] arr4 = {1,2,3};
Object[] arr5 = {arr, arr2}; // basically an int[][]
Object[] arr6 = {arr3, arr4}; // basically an int[][]
Object[] arr7 = {arr5, arr6}; // basically an int[][][]
// etc.
Note that one array doesn't have to contain arrays of the same dimensions:
Object[] arr7 = {arr5, arr};
To prevent this (and to allow for easier access to the data), I suggest writing a class which has an Object member (which will be your int[] or Object[]) and a depth variable and some nice functions to give you access to what you want.
ArrayLists will also work:
ArrayList array = new ArrayList();
array.add(new ArrayList());
array.add(new ArrayList());
((ArrayList)array.get(0)).add(new ArrayList());
// etc.
As your N increases going with nested arrays becomes less and less advantageous, especially when you have a grid structure. Memory usage goes up exponentially in N with this approach and the code becomes complex.
If your grid is sparsely populated (a lot of cells with the same value) you can instead have a collection of Cell objects where each of these holds a coordinate vector and the integer value of the cell. Every cell that is not in the collection is assumed to have a default value, which is your most common value.
For faster access you can use for example a k-d tree (https://en.wikipedia.org/wiki/K-d_tree) but that depends a bit on your actual use-case.
#Andy Thomas explains how to do this using Object[] for the higher levels of the multidimensional array. Unfortunately, this means that the types are not correct to allow indexing, or indeed to allow element access without typecasts.
You can't do this:
Object[] array = ...
int i = array[1][2][3][4];
To get types that allow you to do the above, you need to create an object whose real type is (for example) int[][][][].
But the flipside is that it is not really practical to use that style of indexing for N dimensional arrays where N is a variable. You can't write Java source code to do that unless you place a bound on N (i.e. up to 5) and treat the different cases individually. That becomes unmanageable very quickly.
You can use Java reflection as Arrays are objects.
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException {
Class<?> intClass = int.class;
Class<?> oneDimensionalArrayClass = Class.forName("[I");
Object oneDimensionalIntArray1 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray1, 0, 1);
Object oneDimensionalIntArray2 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray2, 0, 2);
Object oneDimensionalIntArray3 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray3, 0, 3);
Object twoDimensionalIntArray = Array.newInstance(oneDimensionalArrayClass, 3);
Array.set(twoDimensionalIntArray, 0, oneDimensionalIntArray1);
Array.set(twoDimensionalIntArray, 1, oneDimensionalIntArray2);
Array.set(twoDimensionalIntArray, 2, oneDimensionalIntArray1);
System.out.println(Array.get(Array.get(twoDimensionalIntArray, 1), 0));
}
The class Array with its static methods gives access on items while you can specify the dimension of your arrays with the number of leading "[".
The whole construct of multi-dimensional arrays is just the compiler doing some work for you on a big block of memory (ok as some have commented in java this is multiple blocks of memory). One way to deal with the problem you face is to use nested arraylists at runtime. Another (more performant) way is to just allocate a single-dimensional array of the size you need and do the indexing yourself. You could then hide the indexing code in a method that was passed all the details like an array de-reference.
private int[] doAllocate(int[] dimensions)
{
int totalElements = dimensions[0];
for (int i=1; i< dimensions.length; i++)
{
totalElements *= dimensions[i];
}
int bigOne = new int[totalElements];
return bigOne;
}
private int deReference(int[] dimensions, int[] indicies, int[] bigOne)
{
int index = 0;
// Not sure if this is only valid when the dimensions are all the same.
for (int i=0; i<dimensions.length; i++)
{
index += Math.pow(dimensions[i],i) * indicies[dimensions.length - (i + 1)];
}
return bigOne[index];
}
Fields like you wrote above a checked and created by the compiler. If you want a dynamic data structure during runtime you could create your own data structure. Search for Composite Pattern. A small snippet should show you how it works:
interface IGrid {
void insert(IGrid subgrid);
void insert(int[] values);
}
class Grid implements IGrid {
private IGrid subgrid;
void insert(IGrid subgrid) {this.subgrid = subgrid;}
void insert(int[] values) {/* Do nothing */}
}
class SubGrid implements IGrid {
private int[] values;
void insert(IGrid subgrid) {/* Do nothing */}
void insert(int[] values) {this.values = values;}
}
You could simply create a Subgrid for int[] or a Grid with a Subgrid for int[][]. It's only a rudimental solution, you would have to create some code for working on your automaton's levels and values. I would do it this way. Hope it will help :) And look forward for more solutions^^

Assign Object array with Integer elements to Integer array

I searched the internet but didn't found any appropriate solution.
In my application I've got an array of integers. I need to access (assign to) the array via reflection. The application creates an object array that contains Integer elements. Java doesn't allow to assign this Object array to the Integer array.
Is it not possible in Java? My application only knows the Class Object of the Integer array field. The code is dynamically. The type may be an arbitrary type.
private final Integer[] destArray = new Integer[2];
public static void main(final String[] args) throws Exception {
final ReloadDifferentObjectsTest o = new ReloadDifferentObjectsTest();
final Object[] srcArray = {Integer.valueOf(1), Integer.valueOf(2)};
final Field f = o.getClass().getDeclaredField("destArray");
f.setAccessible(true);
// first trial
// f.set(o, srcArray);
// second trial
// Object tmpArray = Array.newInstance(f.getType().getComponentType(), srcArray.length);
// tmpArray = Arrays.copyOfRange(srcArray, 0, srcArray.length);
// f.set(o, tmpArray);
// third trial
Object tmpArray = Array.newInstance(f.getType().getComponentType(), srcArray.length);
tmpArray = f.getType().getComponentType().cast(Arrays.copyOfRange(srcArray, 0, srcArray.length));
f.set(o, tmpArray);
}
No, you can't cast a value which is actually a reference to an instance of Object[] to an Integer[] variable - and that's a good thing. Imagine if that were valid... consider:
Object[] values = { new Integer(5), new Integer(10) };
Integer[] integers = values;
Integer x = integers[0]; // Okay so far
values[0] = new Object(); // Sneaky!
Integer y = integers[0]; // ??? This would have to fail!
If you want to cast something to Integer[], it has to actually be an Integer[]. So this line:
final Object[] srcArray = {Integer.valueOf(1), Integer.valueOf(2)};
... needs to change to create an instance of Integer[].
Yes, the type of a Java array is covariantly linked to its element type. Specifically, Object[] is a supertype of Integer[] and as such is not assignment-compatible with it. You must create an Integer[] at the outset to be able to assign it to an Integer[]-typed variable. From your posted code I can see no reason why you would not do that.
Ok, found the solution... I've got to set each single element via reflection:
// fourth trial
final Object tmpArray = Array.newInstance(f.getType().getComponentType(), srcArray.length);
for (int i = 0; i < srcArray.length; i++) {
Array.set(tmpArray, i, srcArray[i]);
}
f.set(o, tmpArray);

Array of classes which create instances

having Obj class which in his constructor has System.out.println("Hello world!") ;
I create an array of this class using - Obj[] objArray = new Obj[10] ; and nothing printed , means - no instance of Obj has been called . Is there any way to create such array ,but with instances , beyond create them in for loop ?
Well, since you want to know a way apart from using a for loop, you can do this: -
Obj[] objArray = {new Obj(), new Obj(), new Obj()};
What happens here is, you are initializing your array reference directly with array elements.
Now the type of actual array object is inferred from type of array reference on the LHS.
So, with that declaration, an array of size 3 (in the above case) is created, with each index in the array initialized with the instance of Obj class in the given order.
A better way that I would suggest is to use an ArrayList, in which case, you have double-braces initialization to initialize your List without for loop. And plus with an added advantage that you can anytime add new elements to it. As it dynamically increasing array.
List<Object> list = new ArrayList<Object>() {
{
add(new Obj());
add(new Obj());
add(new Obj());
}
}; // Note the semi-colon here.
list.add(new Obj()); // Add another element here.
Answers so far are good and helpful. I'm here just to remind you about
Obj[] objArray = new Obj[10];
Arrays.fill(objArray, new Obj());
Though, this will only assign one reference (to a new Obj()) to all of the elements of array.
When you do Obj[] objArray = new Obj[10] ;
You only create an array of references to point to the actual 'Obj` object.
But in your case the actual Obj object is never created.
for (int i = 0; i < objArray.length; i++) {
objArray[i] = new Obj();
}
Doing above will print the desired.
Finally do System.out.println(Arrays.deepToString(objArray)) to print toString() of all the Obj
Obj[] objArray = new Obj[10] ; just creates an array capable of holding 10 Objs. To place Objs into the array you need to either use Rohit's approach or write a simple for loop to initialize the array entries one at a time:
for (int i = 0; i < 10; i++) {
objArray[i] = new Obj();
}
Or, without a for loop:
int i = 0;
while (i < 10) {
objArray[i] = new Obj();
i++;
}

How can I dynamically add items to a Java array?

In PHP, you can dynamically add elements to arrays by the following:
$x = new Array();
$x[] = 1;
$x[] = 2;
After this, $x would be an array like this: {1,2}.
Is there a way to do something similar in Java?
Look at java.util.LinkedList or java.util.ArrayList
List<Integer> x = new ArrayList<Integer>();
x.add(1);
x.add(2);
Arrays in Java have a fixed size, so you can't "add something at the end" as you could do in PHP.
A bit similar to the PHP behaviour is this:
int[] addElement(int[] org, int added) {
int[] result = Arrays.copyOf(org, org.length +1);
result[org.length] = added;
return result;
}
Then you can write:
x = new int[0];
x = addElement(x, 1);
x = addElement(x, 2);
System.out.println(Arrays.toString(x));
But this scheme is horribly inefficient for larger arrays, as it makes a copy of the whole array each time. (And it is in fact not completely equivalent to PHP, since your old arrays stays the same).
The PHP arrays are in fact quite the same as a Java HashMap with an added "max key", so it would know which key to use next, and a strange iteration order (and a strange equivalence relation between Integer keys and some Strings). But for simple indexed collections, better use a List in Java, like the other answerers proposed.
If you want to avoid using List because of the overhead of wrapping every int in an Integer, consider using reimplementations of collections for primitive types, which use arrays internally, but will not do a copy on every change, only when the internal array is full (just like ArrayList). (One quickly googled example is this IntList class.)
Guava contains methods creating such wrappers in Ints.asList, Longs.asList, etc.
Apache Commons has an ArrayUtils implementation to add an element at the end of the new array:
/** Copies the given array and adds the given element at the end of the new array. */
public static <T> T[] add(T[] array, T element)
I have seen this question very often in the web and in my opinion, many people with high reputation did not answer these questions properly. So I would like to express my own answer here.
First we should consider there is a difference between array and arraylist.
The question asks for adding an element to an array, and not ArrayList
The answer is quite simple. It can be done in 3 steps.
Convert array to an arraylist
Add element to the arrayList
Convert back the new arrayList to the array
Here is the simple picture of it
And finally here is the code:
Step 1:
public List<String> convertArrayToList(String[] array){
List<String> stringList = new ArrayList<String>(Arrays.asList(array));
return stringList;
}
Step 2:
public List<String> addToList(String element,List<String> list){
list.add(element);
return list;
}
Step 3:
public String[] convertListToArray(List<String> list){
String[] ins = (String[])list.toArray(new String[list.size()]);
return ins;
}
Step 4
public String[] addNewItemToArray(String element,String [] array){
List<String> list = convertArrayToList(array);
list= addToList(element,list);
return convertListToArray(list);
}
You can use an ArrayList and then use the toArray() method. But depending on what you are doing, you might not even need an array at all. Look into seeing if Lists are more what you want.
See: Java List Tutorial
You probably want to use an ArrayList for this -- for a dynamically sized array like structure.
You can dynamically add elements to an array using Collection Frameworks in JAVA. collection Framework doesn't work on primitive data types.
This Collection framework will be available in "java.util.*" package
For example if you use ArrayList,
Create an object to it and then add number of elements (any type like String, Integer ...etc)
ArrayList a = new ArrayList();
a.add("suman");
a.add(new Integer(3));
a.add("gurram");
Now you were added 3 elements to an array.
if you want to remove any of added elements
a.remove("suman");
again if you want to add any element
a.add("Gurram");
So the array size is incresing / decreasing dynamically..
Use an ArrayList or juggle to arrays to auto increment the array size.
keep a count of where you are in the primitive array
class recordStuff extends Thread
{
double[] aListOfDoubles;
int i = 0;
void run()
{
double newData;
newData = getNewData(); // gets data from somewhere
aListofDoubles[i] = newData; // adds it to the primitive array of doubles
i++ // increments the counter for the next pass
System.out.println("mode: " + doStuff());
}
void doStuff()
{
// Calculate the mode of the double[] array
for (int i = 0; i < aListOfDoubles.length; i++)
{
int count = 0;
for (int j = 0; j < aListOfDoubles.length; j++)
{
if (a[j] == a[i]) count++;
}
if (count > maxCount)
{
maxCount = count;
maxValue = aListOfDoubles[i];
}
}
return maxValue;
}
}
This is a simple way to add to an array in java. I used a second array to store my original array, and then added one more element to it. After that I passed that array back to the original one.
int [] test = {12,22,33};
int [] test2= new int[test.length+1];
int m=5;int mz=0;
for ( int test3: test)
{
test2[mz]=test3; mz++;
}
test2[mz++]=m;
test=test2;
for ( int test3: test)
{
System.out.println(test3);
}
In Java size of array is fixed , but you can add elements dynamically to a fixed sized array using its index and for loop. Please find example below.
package simplejava;
import java.util.Arrays;
/**
*
* #author sashant
*/
public class SimpleJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try{
String[] transactions;
transactions = new String[10];
for(int i = 0; i < transactions.length; i++){
transactions[i] = "transaction - "+Integer.toString(i);
}
System.out.println(Arrays.toString(transactions));
}catch(Exception exc){
System.out.println(exc.getMessage());
System.out.println(Arrays.toString(exc.getStackTrace()));
}
}
}

Categories

Resources