I have a simple question ?
String[] names = null ;
names[0] = "Hello"
I'm getting an error ..
How could I instantiate array as I don't know the the size limit... help me
Use ArrayList<String> when you don't know in advance the array size. What you are doing here is invalid (trying to access a null object).
Edit: as you can't use Vector and ArrayList, you'll have to roll you own implementation of dynamic array. You'll find one almost ready with some explanations on algolist.net. Simply replace the int storage by a String storage.
// Warning: not tested!
public class DynamicStringArray {
private String[] storage;
private int size;
public DynamicArray() {
storage = new String[10];
size = 0;
}
public DynamicArray(int capacity) {
storage = new String[capacity];
size = 0;
}
public void ensureCapacity(int minCapacity) {
int capacity = storage.length;
if (minCapacity > capacity) {
int newCapacity = (capacity * 3) / 2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
storage = Arrays.copyOf(storage, newCapacity);
}
}
private void pack() {
int capacity = storage.length;
if (size <= capacity / 2) {
int newCapacity = (size * 3) / 2 + 1;
storage = Arrays.copyOf(storage, newCapacity);
}
}
public void trim() {
int newCapacity = size;
storage = Arrays.copyOf(storage, newCapacity);
}
//...
}
How about this?
String[] names = new String[] { "Hello" };
Or you might also use ArrayList or StringCollection.
EDIT:
For J2ME: There was a trick posted here for dynamic array of Ints. I suppose it should possible to convert it for Strings. I have converted that example, however I didn't have J2ME emulator to test it:
public class DynamicStringArray {
private static final int CAPACITY_INCREMENT = 10;
private static final int INITIAL_CAPACITY = 10;
private final int capacityIncrement;
public int length = 0;
public String[] array;
public DynamicStringArray(int initialCapacity, int capacityIncrement) {
this.capacityIncrement = capacityIncrement;
this.array = new String[initialCapacity];
}
public DynamicStringArray() {
this(CAPACITY_INCREMENT, INITIAL_CAPACITY);
}
public int append(String str) {
final int offset = length;
if (offset == array.length) {
String[] old = array;
array = new String[offset + capacityIncrement];
System.arraycopy(old, 0, array, 0, offset);
}
array[length++] = str;
return offset;
}
public void removeElementAt(int offset) {
if (offset >= length) {
throw new ArrayIndexOutOfBoundsException("offset too big");
}
if (offset < length) {
System.arraycopy(array, offset + 1, array, offset, length - offset
- 1);
length--;
}
}
}
try
String[] names = new String[1];
names[0] = "Hello";
Use an ArrayList<String> if you don't know the size beforehand.
ArrayList<String> names = new ArrayList<String>();
names.add("hello");
names.add("another string");
...
looks like j2me has non-generic ArrayList that you could use like this.
ArrayList names = new ArrayList();
names.add("hello");
names.add("another string");
....
String name = (String) names.get(1);
How could i instantiate array as I dont know the the size limit
Sorry, that cannot be done. Arrays are of fixed size in Java, and you have to give the size when you create the array.
If you need a flexible buffer, consider using an ArrayList instead. That will grow as needed.
If you don't know the size limit (or more generally: almost always) you'll want to use a List instead of an array, because it's much more comfortable to handle.
List<String> names = new ArrayList<String>();
names.add("Hello");
The reason you're getting an exception (a NullPointerException) is that you only defined a variable to reference a String-array, but created no String array.
You'd have to initialize it like this:
String[] names = new String[10];
As you explained yo want to use it at J2ME there is no ArrayList provided for J2ME however there is an implementation here:
http://kickjava.com/src/j2me/util/ArrayList.java.htm
You can try it.
Also you should consider here too:
http://www1.j2mepolish.org/javadoc/j2me/de/enough/polish/util/ArrayList.html
As you are on J2ME and say you can't use arraylist I don't see you having any choice.
You need to choose a reasonable starting size for your array, watch the size, and if you need to add more objects than the size, copy it to a larger array.
With our constraints I cannot think of another way.
you can use with vector
Vector strings=new Vector();
strings.addElement("HELLO");
//then convert it to string array
String str[]=new String[strings.size()];
str[0]=(String)strings.get(0);
like this..
Hope this helpfull
String str[] = { "ABCde","xyZ","sdsdsdf"} ;
String str[][] = { {"ABC","abc"} ,
{"pqr","qwerTY"}
} ;
Related
String[] mySecret;
String[] colours = {"R","Y","Bl","G","O","Pu","Pi","Br"};
public void getuserInput() {
numColours = min + (int)(Math.random() * ((max-min) +1));
numPegs = min + (int)(Math.random() * ((max-min) +1));
}
public void setSecret() {
for (i=0; i<numColours; i++) {
mySecret[i] = colours[new Random().nextInt(colours.length)];
}
}
This is a small part of my code. When I run this, I get a NullPointerException. Is there any other way to get mySecret which is meant to be a string array to contain a specified number of colours but chosen at random from the colours string array. Any help would be appreciated, thanks.
You shoud initialize your array mySecret like this:
String[] colours = {"R","Y","Bl","G","O","Pu","Pi","Br"};
String[] mySecret = new String[colours.length];
You need to read up on the Java language a bit more.
public void setSecret() {
mySecret = new String[numColours];
for ( int i=0; i<numColours; i++) {
mySecret[i] = colours[new Random().nextInt(colours.length)];
}
}
I wrote this test,
public class test {
public static String[] foo(String[] myArray, int index) {
myArray[index] = "world";
return myArray;
}
public static void main(String[] args) {
String[] fooArray = new String[10];
for (int i = 0; i < 10; i ++) {
fooArray[i] = "hello";
}
foo(fooArray, 9);
for (int i = 0; i < 10; i ++) {
System.out.println(fooArray[i]);
}
}
}
which results in this output
hello
hello
hello
hello
hello
hello
hello
hello
hello
world
So foo basically just changes a value in the array and returns this modified array. But the actual fooArray is being modified by the foo method (as evidenced by the output). Is there an efficient way to pass the array fooArray and have it not modified by foo?
I know that I could make a copy of the fooArray in the method like
public String[] void foo(String[] myArray, int index) {
String[] copy = new String[];
for (int i = 0; i < 10; i ++) {
copy[i] = myArray[i];
}
copy[index] = "world";
return copy;
}
but I am planning to do this modification on arrays of a size in the thousands and also I am planning to this millions (or even billions) of times during runtime so I don't think that copying the entire array every time would be an efficient solution (I need to get a reasonable runtime).
I think the best solution is Arrays.copyOf(...)
It uses System.arraycopy(...)
for example in Arrays.java you can find:
public static byte[] copyOf(byte[] original, int newLength) {
byte[] copy = new byte[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
And the documentation says it is efficient because it is native method and just copies the old block of memory to new one.
Simply do fooArray.clone()
For example:
foo(fooArray.clone(), 9);
This will clone the array and when you call foo it will not modify fooArray.
I am getting the error now that BookCollection.java:67: error: incompatible types
collection[lastElement++] = b;
Also am not sure if my constructor is set up correctly? The directions were:
Constructor:
Given a parameter specifying the limit on the collection size, an empty book collection is created using the given parameter. The parameter should not exceed the preset maximum size 200.
Am I initializing my variables correctly then? An answer below helped me change my code, but although I do not get errors within my constructor, I feel as though it may not be correct according to the directions....
I'll paste the couple chunks of my code that pertain to the question.
public class BookCollection{
//data fields, need complete
private int limit = 200;
//Array of type book
private int Book[];
//actual size of collection, initialized to zero. Must never exceed limit
private int collection[];
private int lastElement;
//Constructor
public BookCollection(int l, int c[], int le,int b[]){
Book = b;
collection = c;
limit = l;
lastElement = le;
int lastElement = 0;
if(limit <= 200){
Book[] collection = new Book[limit];
} else{
throw new UnsupportedOperationException("CannotExceedLimit");
}
}
ANNDDDD where I am getting the error:
public void addBook(int b[], int c[]) {
Book = b;
collection = c;
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You have not declared i as an integer in your for loop. So add the declaration with initialization. Replace this
for(i=0; i<collection.length; i++){
with
for(int i=0; i<collection.length; i++){
This statement
BookCollection[] collection = new BookCollection[limit]; //initialize array of 200
declares a local array. It gets destroyed as soon as you leave the constructor.
The collection that stays around is this one:
private int collection[];
It consists of ints, so when you try to do this
collection[i].add(b);
the compiler correctly complains that int does not have a method called add.
Good chances are, even declaring the collection as
private Book[] collection;
and initializing it in the constructor as
collection = new Book[limit];
is not going to help, though: unlike collections, Java arrays do not let you change their size dynamically, so you need to store an index of the last element of the collection[] array that has been set.
This leads to understanding that you need a loop for finding duplicates, and noting else: define an element int lastElement, set it to zero in the constructor, and rewrite the addBook method as follows:
public void addBook(Book b) {
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You did't declared i as a int type variable, make it as
for(int i=0; i<collection.length; i++){
^here
//...
}
I'm quite new to Java, but getting into it. However, I can't wrap my head around why this example, which I found here, does not work:
At start of class:
String[][] spritesPaint = new String[20][20];
In method:
for (int funct1 = 0; funct1 <= 2; funct1++) {
if (funct1 == 0) {
for (int funct2 = 0; funct2 < rEnemyNumber; funct2++) {
spritesPaint[0][funct2] = new Integer(rEnemyY[funct2])
.toString();
spritesPaint[1][funct2] = rEnemyGraphic[funct2];
}
} else if (funct1 == 1) {
Arrays.sort(Integer.valueOf(spritesPaint[0].toString()),
new Comparator<Integer[]>() {
#Override
public int compare(final Integer[] entry1,
final Integer[] entry2) {
final Integer time1 = entry1[0];
final Integer time2 = entry2[0];
return time1.compareTo(time2);
}
});
} else if (funct1 == 2) {
for (int funct3 = 0; funct3 < rEnemyNumber; funct3++) {
if (rEnemyCheck[funct3] == true) {
nextPaint = getImage(base, rEnemyGraphic[funct3]);
System.out.println("Next: " + nextPaint);
g.drawImage(nextPaint, rEnemyX[funct3] + worldCenterX,
rEnemyY[funct3] + worldCenterY, this);
}
}
}
}
Basically, what I want to do is have a two dimensional array where I store Y position of object on the screen and an image path also related to that object, then sort it by the Y position integer. This should allow me to paint elements to the screen in the correct order for an isometric perspective.
However, I keep getting this error:
The method sort(T[], Comparator<? super T>) in the type Arrays
is not applicable for the arguments (Integer, new Comparator<Integer[]>(){})
Please help me, I've been twisting my brain for hours trying to understand why I get this error now.
Integer.valueOf(spritesPaint[0].toString()) is a single integer, however from your description it seems that you want to sort the strings in the 1-dimensional array spritesPaint[0] as if they were integers. Here is a modification that will do just that:
Arrays.sort(spritesPaint[0], new Comparator<String>() {
#Override public int compare(final String entry1, final String entry2) {
final Integer time1 = Integer.valueOf(entry1);
final Integer time2 = Integer.valueOf(entry2);
return time1.compareTo(time2);
}
});
Alternatively, if you are trying to sort the first dimension of the array by the first element of the second dimension of the array, modify as follows:
Arrays.sort(spritesPaint, new Comparator<String[]>() {
#Override public int compare(final String[] entry1, final String[] entry2) {
final Integer time1 = Integer.valueOf(entry1[0]);
final Integer time2 = Integer.valueOf(entry2[0]);
return time1.compareTo(time2);
}
});
The error message means that, instead of passing an Array of type T (generic), you are passing an Integer. So, where you have:
Arrays.sort(Integer.valueOf(spritesPaint[0].toString()), ...
you want to pass in
Arrays.sort(arrayToBeSorted, ...
(Also, your variables could do with better names because I really don't understand what this example is doing...)
I want a function / data structure that can do this:
func(int dim){
if(dim == 1)
int[] array;
else if (dim == 2)
int[][] array;
else if (dim == 3)
int[][][] array;
..
..
.
}
anyone know how?
Edit
Or you could use Array.newInstance(int.class, sizes). Where sizes is an int[] containing the desired sizes. It will work better because you could actually cast the result to an int[][][]...
Original Answer
You could use the fact that both int[] and Object[] are Objects. Given that you want a rectangular multidimensional array with sizes given by the list sizes
Object createIntArray(List<Integer> sizes) {
if(sizes.size() == 1) {
return new int[sizes.get(0)];
} else {
Object[] objArray = new Object[sizes.get(0)];
for(int i = 0; i < objArray.length; i++) {
objArray[i] = createIntArray(sizes.subList(1, sizes.size());
}
return objArray;
}
}
You lose all static type checking, but that will happen whenever you want a dynamically dimensioned array.
If your purpose is to create a truly dynamic array, then you should look at the Array object in the JDK. You can use that to dynamically generate an array of any dimension. Here is an example:
public void func(int dim) {
Object array = Array.newInstance(int.class, new int[dim]);
// do something with the array
}
Once the array Object has been created, you can use the methods of the java.lang.reflect.Array class to access, add, remove elements from the multi-dimension array that was created. In also includes utility methods to determine the length of the array instance.
You can even check the dimension of the array using:
public int getDimension(Object array) {
int dimension = 0;
Class cls = array.getClass();
while (cls.isArray()) {
dimension++;
cls = cls.getComponentType();
}
return dimension;
}
People have post good solutions already, but I thought it'd be cool (and good practice) if you wrap the dynamic multidimensional array into a class, which can use any data structure to represent the multi-dimensional array. I use hash table so you have virtually unlimited size dimensions.
public class MultiDimArray{
private int myDim;
private HashMap myArray;
public MultiDimArray(int dim){
//do param error checking
myDim = dim;
myArray= new HashMap();
}
public Object get(Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
Object obj = myArray;
for (int i = 0; i < myDim; i++){
if(obj == null)
return null;
HashMap asMap = (HashMap)obj;
obj = asMap.get(indexes[i]);
}
return obj;
}
public void set(Object value, Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
HashMap cur = myArray;
for (int i = 0; i < myDim - 1; i++){
HashMap temp = (HashMap)cur.get(indexes[i]);
if (temp == null){
HashMap newDim = new HashMap();
cur.put(indexes[i], newDim);
cur = newDim;
}else{
cur = temp;
}
}
cur.put(indexes[myDim -1], value);
}
}
and you can use the class like this:
Object myObj = new Object();
MultiDimArray array = new MultiDimArray(3);
array.put(myObj, 0, 1, 2);
array.get(0, 1, 2); //returns myObj
array.get(4, 5, 6); //returns null
What about a class like following?
class DynaArray {
private List<List> repository = new ArrayList<List>();
public DynaArray (int dim) {
for (int i = 0; i < dim; i++) {
repository.add(new ArrayList());
}
}
public List get(int i) {
return repository.get(i);
}
public void resize(int i) {
// resizing array code
}
}