I'm attempting to create a Java object array and place the array inside itself at its second index (in order to represent a self-similar fractal with the array), but when I try to access theArray[1][1][0], I get this error:
Main.java:11: error: array required, but Object found.
This is what I've tried so far, and I'm not sure why it's not working:
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
Object[] theArray = new Object[2];
theArray[0] = "This array should contain itself at its second index.";
theArray[1] = theArray; //Now I'm attempting to put the array into itself.
System.out.println(theArray[1][1][0]) //Main.java:11: error: array required, but Object found
}
}
Is it actually possible to put a Java array inside itself, as I'm attempting to do here?
theArray[1] is of compile-time type Object (since it comes from an array of Objects).
You need to cast it to Object[] to use it as an array.
The fundamental problem you're encountering is that although an array that contains itself is a perfectly valid object, it isn't a valid type.
You can nest array types arbitrarily deeply – Object[][][][][][][][][][][][][] is a valid type.
However, the "bottom level" of the type can't be an array.
You're trying to create a type which is an array of itself.
Using generics, that would be possible:
class Evil extends ArrayList<Evil> { }
You're running into a casting error since you've declared theArray to be an Array of Objects. As a result, you can't promise Java that theArray[1] is an Array--it could be any kind of Object. You'll need to break up your access to do what you want:
Object[] innerArray = (Object[]) theArray[1];
System.out.println(innerArray[0] == theArray[0]); // Always true since innerArray IS theArray
while (true) {
// Careful! This loops forever!
// set innerArray = innerArray[1] = theArray = theArray[1] = innerArray...
// all of these are the exact same object (but you have to tell Java their type every time)
innerArray = (Object[]) innerArray[1];
System.out.println(innerArray[0]);
}
Your code is equivalent to
Object arr = theArray[1]; // arr is an Object here, not an array
But you could do
Object[] arr = (Object[] ) theArray[1]; // Now it is an array
This can be done quite easily with ArrayLists:
ArrayList list = new ArrayList();
list.add(list);
So now
System.out.println(list.get(0));
and
System.out.println(((ArrayList)list.get(0)).get(0)); //Casting because .get() returns an Object
Both will output the same thing.
You can take this to an arbitrarily large number of levels, if you want to:
System.out.println(((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)((ArrayList)list.get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0)).get(0));
Related
I'm doing a school assignment where I need to pass an array into a method. The array declaration is as follows:
static Object[] myArray = new String[8];
It is called here (Proj04Runner is the class we are asked to create for the assignment):
Proj04Runner runner = new Proj04Runner();
myArray = runner.runA(myArray);
I tried to make a method in my Proj04Runner class called runA, but I keep getting error messages. I have tried:
Collection runA(Object[] myArray){
and
Collection runA(Collection myArray){
but get error messages both times. The error messages are, respectively:
Proj04.java:60: error: incompatible types: Collection cannot be converted to Object[]
Proj04.java:60: error: incompatible types: Object[] cannot be converted to Collection
What am I doing wrong?
You are trying to assign the result back to myArray. You can't do that. Because the type of myArray is static Object[]. You fix it by defining a new variable to hold the result. Like,
Collection myCollection = runner.runA(myArray);
Note: It's a bad idea to use rawtypes in Java. Collection is a generic type. It should be some kind of Collection<Type>. Also, in Proj04Runner it should be
Collection runA(Object[] myArray) { // <-- takes an `Object[]`
Finally, you haven't shown much code. But you are running Proj04 (not Proj04Runner).
New to Java, and OOP in general.
I'm doing an online Lynda course, and in the course there's an example of using Array.get to extract the 2nd item from an array:
String[] myFavoriteCandyBars = {"Twix", "Hershey's", "Crunch"};
System.out.println(Array.get(myFavoriteCandyBars, 2));
And the instructor explained that get is a static method from the "Array" class.
But when I tried defining:
`Array[] testarray = new Array[10];`
And using:
`testarray.get(testarray[10]);`
I get an error:
cannot resolve method 'get(java.lang.reflect.Array)'
But I don't understand why - the testarray is an object of class Array, and class Array has a method "get", so although it's bad practice, why can't I do it?
The Array class is an internal Java class containing only public static methods, and its intended use is to not be be directly instantiated. The following code:
testarray.get(testarray[10]);
fails because testarray is of type Array[], not Array, and therefore does not have the static method get() available. Hypothetically speaking, if you could call Array#get on an instance, it should work, but as mentioned above, Array cannot be instantiated.
A more typical way to use Array would be something like:
String[] testarray = new String[10];
testarray[1] = "Snickers";
System.out.println(Array.get(testarray, 1));
That is, create an array of the desired type, and then use Array#get to access whichever element you want.
get() is not a method in the array class, (as in a byte[] object). get() is in the Array class. Doing Array.get(testarray, 0) is what you want. Despite that, don't do this, do testarray[0] instead.
Whenever you use a static method, you shouldn't call it from an object, you should use the class instance, so instead of doing
Object o = new Object();
o.staticMethod();
Do:
Object.staticMethod();
I wrote a function that would take variable arguments as object.
When I passed in an array of ints of size 1 eg {9}, it treated args[0] as and int array[] than an int so the valueOf did not produce 9.
But If passed in and array of 2 or more ints eg {9,11} then it treated args[0] as 9 and args[1] as 11.
Why does it behave differently.
Note it is being written for Android.
protected String[] whereArgs(Object...args) {
String[] argsStrings = new String[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String){
argsStrings[i] = (String)args[i];
} else {
argsStrings[i] = String.valueOf(args[i]);
}
}
return argsStrings;
}
EDIT Just had a look again I was actually passing them differently in the two ints scenario, one by one and not in an array, sorry.
Why doesn't it split the method(Object...args) into an array of objects when I pass in an array of ints, like what happens with method(int...args)
So now to get the string value I have to individually cast the type of array eg. for int[], double[]
if (args[0] instanceof int[]){
argsStrings[0] = String.valueOf(((int[])args[0])[0]);
Is there a way to write it for any type of object as this causes a crash
argsStrings[0] = String.valueOf(((Object[])args[0])[0]);
java.lang.ClassCastException: int[] cannot be cast to java.lang.Object[]
If you want to pass an array and treat each item as a separate item of the 'args' parameter of your method.. you need to cast your array to an Object[]. e.g: If you pass in your array of integers like below it will do what you want.
whereArgs((Object[])(new Integer[]{1, 2}))
The reason for this is when the source is compiled var-arg methods are actually replaced by an array. all places where the method is being called is converted to an array. If you want to pass an array so that each item becomes a separate argument.. then you need to use the correct array type. in your scenario this will be Object[]. This lets the compiler know that it can leave the method call as it is (without putting the arguments inside a new object[])
i have an array of strings which i want to convert to int, pretty simple and straightforward here is the code :
public static void main(String[] args) {
String myarray[]=readfile("[pathtothefile]");
int mynums[] = new int[myarray.length];
for (int i=0;i<myarray.length;i++){
mynums[i]=Integer.parseInt(myarray[i]);
}
System.out.print(Arrays.toString(mynums));
}
But the Problem here is, if i initialize "mynums" like this: mynums[]=null; i get NullPointerException on the following line:
"mynums[i]=Integer.parseInt(myarray[i]);"
what i have to do to solve it is
int mynums[] = new int[myarray.length];
here someone explained why it happens but i dont know how to initialize now! i mean sometimes i dont know how big my array can get and i just want to initialize it. is it even possible?
In Java everything is a pointer behind the scenes. So when you do mynums[]=null, you are pointing to a null. So what is null[i]? That is where your NPE comes from. Alternatively when you point it to an array, then you are actually accessing the i'th element of the array.
You have to first initialize the array because it allocates memory depending on the array size. When you want to add for example an integer to an array it writes the int into previously allocated memory.
The memory size won't grow bigger as you add more items.( Unless you use Lists or Hashmaps, ... but it's not true for generic arrays)
If you don't know how big your array will be, consider using SparseIntArray. which is like Lists and will grow bigger as you add items.
Briefly, in java an array is an object, thus you need to treat it like an object and initialize it prior to doing anything with it.
Here's an idea. When you're initializing something as null, you're simply declaring that it exists. For example ... if I told you that there is a dog, but I told you nothing about it ... I didn't tell you where it was, how tall it was, how old, male/female, etc ... I told you none of its properties or how to access it, and all I told you was that there IS a dog (whose name is Array, for sake of argument), then that would be all you know. There's a dog whose name is Array and that is it.
Typically, arrays are used when the size is already known and generally the data is meant to be immutable. For data that are meant to be changed, you should use things like ArrayList. These are intended to be changed at will; you can add/remove elements at a whim. For more information about ArrayList, read up on the links posted above.
Now, as for your code:
public static void main(String[] args) {
ArrayList<int> myInts = new ArrayList<int>();
// define a new null arraylist of integers.
// I'm going to assume that readfile() is a way for you get the file
// into myarray. I'm not quite sure why you would need the [], but I'll
// leave it.
String myarray[] = readfile("[pathtothefile]");
for (int i = 0; i < myarray.length; i++) {
//adds the value you've specifed as an integer to the arraylist.
myInts.add(Integer.parseInt(myarray[i]));
}
for (int i = 0; i < myInts.size(); i++) {
//print the integers
System.out.print(Integer.toString(myInts.get(i)));
}
}
What if you don't use an array but an ArrayList? It grows dynamically as you add elements.
i know how to hard code an algorithm on how to check the types of each object in an arraylist, but is there any other way in checking the type of that ArrayList<> in one go, i mean my application has only three types of arraylist. Say i have a function that returns an ArrayList, and its definiton is that in a variable o (its an arraylist of object ofcourse) i'll add a person object,
o.add(person);
and having added all person data on an arraylist of objects and when a call this function say the name of my function is getData(),
ArrayList <Object> obj = getData();
so i know that in that ArrayList that i returned from calling getData() that it is all person object, how do i know the type of that ArrayList?.
Just wanted that function to be more generic in sense, this is for my application though, geniric troughout my application.
Is there any other way of doing this, i can think of an algorithm but is there any short cut or easy way of doing this?..
There is no such thing as 'the type' of an ArrayList.
The class ArrayList stores a list of Object references. It doesn't know and doesn't care if they are all of some type.
The Java generic system adds compile-time checking to help you keep track of types. So, if you declare ArrayList<Person>, you will get compile errors if you write code that could insert a non-Person into your list.
At runtime, the only way to tell what is in an ArrayList to iterate over all the contained items and check them with instanceof.
Actually there is a way without casting every item manually(it still is ugly though..)
//start with an arraylist of unknown generic type
ArrayList <Object> obj = getData();
//Make an array from it(basically the same as looping over the list
// and casting it to the real type of the list entries)
Object[] objArr = obj.toArray();
//Check if the array is not empty and if the componentType of the
//array can hold an instance of the class Person
if(objArr.length>0
&& objArr.getClass().getComponentType().isAssignableFrom(Person.class)) {
// do sth....
}
This should not give any unchecked warnings.
You could use it like this:
private boolean isArrayOfType(Object[] array,Class<?> aClass) {
return array.length > 0
&& array.getClass().getComponentType().isAssignableFrom(aClass);
}
Object[] personArr = getData().toArray();
if(isArrayOfType(personArr,Person.class) {
//Do anything...
}
What won't work is the following:
// -> This won't work, sry!
ArrayList<Person> personArrayList = Arrays.asList((Person[])personArr);
If the list is not empty, get the first element:
type = this.list.get(0).getClass().getSimpleName();