I am working on a project, but I cannot use any existing java data structures (ie, ArraysList, trees, etc)
I can only use arrays. Therefore, I need to dynamically update an array with new memory.
I am reading from a text file, and I pre-allocate 100 for the arrays memory:
String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null) {
// Store the content into an array
Scanner s = new Scanner(strLine);
while(s.hasNext()) {
wordList[wordCount] = s.next();
wordCount++;
}
}
Now this works fine for under 100 list items. br.readline is the buffered reader going through each line of a textfile. I have it then store each word into list and then increment my index (wordCount).
However, once I have a text file with more than 100 items, I get an allocation error.
How can I dynamically update this array (and thereby sort of reinvent the wheel)?
Thanks!
You can do something like this:
String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
int arrayGrowth = 50;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null) {
// Store the content into an array
Scanner s = new Scanner(strLine);
while(s.hasNext()) {
if (wordList.length == wordCount) {
// expand list
wordList = Arrays.copyOf(wordList, wordList.length + arrayGrowth);
}
wordList[wordCount] = s.next();
wordCount++;
}
}
Using java.util.Arrays.copyOf(String[]) is basically doing the same thing as:
if (wordList.length == wordCount) {
String[] temp = new String[wordList.length + arrayGrowth];
System.arraycopy(wordList, 0, temp, 0, wordList.length);
wordList = temp;
}
except it is one line of code instead of three. :)
You allocate a new Array (double the capacity, for instance), and move all elements to it.
Basically you need to check if the wordCount is about to hit the wordList.size(), when it does, create a new array with twice the length of the previous one, and copy all elements to it (create an auxiliary method to do this), and assign wordList to your new array.
To copy the contents over, you could use System.arraycopy, but I'm not sure that's allowed with your restrictions, so you can simply copy the elements one by one:
public String[] createNewArray(String[] oldArray){
String[] newArray = new String[oldArray.length * 2];
for(int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}
Proceed.
Take a look at implementation of Java ArrayList. Java ArrayList internally uses a fixed size array and reallocates the array once number of elements exceed current size. You can also implement on similar lines.
you can not increase array size dynamically better you copy into new array. Use System.arrayCopy for that, it better than copying each element into new array. For reference
Why is System.arraycopy native in Java?.
private static Object resizeArray (Object oldArray, int newSize) {
int oldSize = java.lang.reflect.Array.getLength(oldArray);
Class elementType = oldArray.getClass().getComponentType();
Object newArray = java.lang.reflect.Array.newInstance(
elementType, newSize);
int preserveLength = Math.min(oldSize, newSize);
if (preserveLength > 0)
System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
return newArray;
}
You have to manually create a new bigger array and copy over the items.
this may help
Visual Basic has a nice function : ReDim Preserve.
Someone has kindly written an equivalent function - you can find it here. I think it does exactly what you are asking for (and you're not re-inventing the wheel - you're copying someone else's)...
Lets take a case when you have an array of 1 element, and you want to extend the size to accommodate 1 million elements dynamically.
Case 1:
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 1];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
Case 2 (increasing size by a addition factor):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 10];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
Case 3 (increasing size by a multiplication factor):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length * 2];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
When extending the size of an Array dynamically, using Array.copy or iterating over the array and copying the elements to a new array using the for loop, actually iterates over each element of the array. This is a costly operation. Array.copy would be clean and optimized, still costly. So, I'd suggest increasing the array length by a multiplication factor.
How it helps is,
In case 1, to accommodate 1 million elements you have to increase the size of array 1 million - 1 times i.e. 999,999 times.
In case 2, you have to increase the size of array 1 million / 10 - 1 times i.e. 99,999 times.
In case 3, you have to increase the size of array by log21 million - 1 time i.e. 18.9 (hypothetically).
public class Arr {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = {1,2,3};
//let a[] is your original array
System.out.println(a[0] + " " + a[1] + " " + a[2]);
int b[];
//let b[] is your temporary array with size greater than a[]
//I have took 5
b = new int[5];
//now assign all a[] values to b[]
for(int i = 0 ; i < a.length ; i ++)
b[i] = a[i];
//add next index values to b
b[3] = 4;
b[4] = 5;
//now assign b[] to a[]
a = b;
//now you can heck that size of an original array increased
System.out.println(a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " "
+ a[4]);
}
}
Output for the above code is:
1 2 3
1 2 3 4 5
Related
I'm new to Java, and I'm not sure how to ask the right question, so please bear with me. I have 40 total items of 6 different types to put into a new array; each item type has a different cost. The first item (quantity=1) costs $3, the second item (qty=2) costs $5 each, the third item (qty=4) costs $9 each, and so on. The quantity of each item type is in numTypeIndArray and the cost for each type is in costCSDriverArray. A cumulative count of the total items is in numTypeCumulArray.
So, the new array, indItemCostArray, should be single dimensional and have 40 elements. It would look something like {3,5,5,9,9,9,9,...,13,13,13}, but the last fifteen elements are a cost of $13. How do I get to this array with 40 elements? I started with trying to fill the array using a nested for loop but I haven't gotten there yet. The code below is plain wrong.
int[] costArray = new int[]{3,5,9,10,11,13};
int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};
int[] indItemCostArray = new int[numTypeCumulArray[6]];
for (int i = 0; i < indItemCostArray.length; i++) {
for (int j = 0; j < numTypeIndArray[i]; j++) {
indItemCostArray[i+j] = costArray[j];
}
}
First of all, you'll get a ArrayOutOfBoundException at:
int[] indItemCostArray = new int[numTypeCumulArray[6]];
The size of the array numTypeCumulArray is 6, and arrays are 0 indexed. So, The last index number is 5, not 6, as indexing started from 0.
You can do as follows for accessing the last element of the array:
int[] indItemCostArray = new int[numTypeCumulArray[numTypeCumulArray.length - 1]];
Secondly, you're running your outer loop for 40 times and for each iteration your inner loop is trying to iterate for numTypeIndArray[i] times, where i is the iterator variable of outer loop. So, surely after sixth iteration, when value of i will be 6, your program will again throw the ArrayOutOfBoundException as you're accessing a value in the terminator condition of the inner loop from numTypeIndArray whose last index is 5.
Again, inside the inner loop, you're assigning indItemCostArray at index position i+j, which will actually far from your purpose.
To achieve what you are exactly expecting, you can do as follows:
int currentIndex =0;
for (int costIndex = 0; costIndex < costArray.length; costIndex++) {
for(int index = currentIndex; index < currentIndex + numTypeIndArray[costIndex]; index++) {
indItemCostArray[index] = costArray[costIndex];
}
currentIndex = numTypeCumulArray[costIndex];
}
Here, what I did is, in the outer loop I iterated the same amount of time the length of costArray, you can take the length of numTypeIndArray instead too, no issue. I've defined a variable named currentIndex to keep track of the current assignable index for array indItemCostArray. In the inner loop, I tried to begin with the currentIndex and loop upto the time same as the number of items needed for that type, given in numTypeIndArray[costIndex], and for each iteration, set the corresponding index of indItemCostArray with the cost of costIndex in the costArray. Finally, I update the currentIndex with the corresponding cumulative total items from numTypeCumulArray.
Hope you got everything clear.
The whole setup of three arrays is kind of weird. The weiredest is the third array. Think carefully, do you actually need it? You already have all the information in your second array. The third array can introduce a lot of unnacessary mistakes.
But, assuming that you actually need these arrays for some reason and there are no mistakes in making these arrays. You can get your required fourth array as follows,
int[] costArray = new int[]{3,5,9,10,11,13};
int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};
// you want to make sure that your arrays are of same lenght
assert(costArray.length == numTypeIndArray.length && costArray.length == numTypeCumulArray.length);
// length of these arrays is unique items count
int uniqueItemsCount = costArray.length;
// totalItemsCount is last element of numTypeCumulArray
int totalItemsCount = numTypeCumulArray[uniqueItemsCount - 1];
int[] indItemCostArray = new int[totalItemsCount];
// use this to keep track of index in indItemCostArray
int itemCostIndex = 0;
for (int i = 0; i < uniqueItemsCount && itemCostIndex < totalItemsCount; i++) {
for (int j = 0; j < numTypeIndArray[i] && itemCostIndex < totalItemsCount; j++) {
indItemCostArray[itemCostIndex] = costArray[j];
// increase the index for next item cost
itemCostIndex += 1;
}
}
int[] costArray = new int[]{3,5,9,10,11,13};
int[] numTypeIndArray = new int[]{1,2,4,7,11,15};
int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};
int[] indItemCostArray = new int[numTypeCumulArray[5]];
int num = 0;
for (int i = 0; i < numTypeIndArray.length; i++) {
for (int j = 0; j < numTypeIndArray[i]; j++) {
indItemCostArray[num + j] = costArray[i];
}
num += numTypeIndArray[i];
}
System.out.println(Arrays.toString(indItemCostArray));
First, you don't need int[] numTypeCumulArray = new int[]{1,3,7,14,25,40};
It just shows the cumulative values of the numTypeIndArray. The last value, 40 is just the sum of numTypeIndArray and that would be the size of the resulting array from your requirement.
It can be summed in a simple for loop or you can do it like this and then create the target array.
int maxSize = Arrays.stream(numTypeIndArray).sum();
int[] indItemCostArray = new int[maxSize];
Then you could proceed to populate the array with the values as has been shown. Here is another way using streams which you will undoubtedly learn about. The quick explanation is that it creates multiple streams of the proper quantities of cost.
e.g
stream1 -> {3}
stream2 -> {5,5};
stream3 -> {9,9,9,9} etc.
Then it flattens them in a single stream of those values and returns an array.
int[] result = IntStream.range(0, costArray.length)
.flatMap(i -> IntStream.range(0, numTypeIndArray[i])
.map(q -> costArray[i]))
.toArray();
But using a class to hold the information would be better. Here is one example.
class Product {
private String name;
private int cost;
private int quantity;
public Product(String name, int cost, int quantity) {
this.name = name;
this.cost = cost;
this.quantity = quantity;
}
public int getCost() {
return cost;
}
public int getQuantity() {
return quantity;
}
public String getName() {
return name;
}
#Override
public String toString() {
return new StringJoiner(", ","[", "]").add(name).add("cost="+cost).add("quantity="+quantity).toString();
}
}
And it can be used like so.
List<Product> products = new ArrayList<>();
for (int i = 0; i < costArray.length; i++) {
products.add(new Product("Item" + (i+1), costArray[i], numTypeIndArray[i]));
}
products.forEach(System.out::println);
Prints
[Item1, cost=3, quantity=1]
[Item2, cost=5, quantity=2]
[Item3, cost=9, quantity=4]
[Item4, cost=10, quantity=7]
[Item5, cost=11, quantity=11]
[Item6, cost=13, quantity=15]
And once again it can be streamed to create your results exactly as before only using the class getters to get the values.
int[] result2 = products.stream()
.flatMapToInt(
prod -> IntStream.range(0, prod.getQuantity())
.map(q -> prod.getCost()))
.toArray();
The two arrays result and result2 are identical. But you may find that using classes may eliminate the requirement for creating such an array.
I found this code online and it works well to permute through the given array and return all possible combinations of the numbers given. Does anyone know how to change this code to incorporate a 2D array instead?
public static ArrayList<ArrayList<Integer>> permute(int[] numbers) {
ArrayList<ArrayList<Integer>> permutations = new ArrayList<ArrayList<Integer>>();
permutations.add(new ArrayList<Integer>());
for ( int i = 0; i < numbers.length; i++ ) {
ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();
for ( ArrayList<Integer> p : permutations ) {
for ( int j = 0, n = p.size() + 1; j < n; j++ ) {
ArrayList<Integer> temp = new ArrayList<Integer>(p);
temp.add(j, numbers[i]);
current.add(temp);
}
}
permutations = new ArrayList<ArrayList<Integer>>(current);
}
return permutations;
}
This is what I have attempted:
public static int[][] permute(int[] numbers){
int[][] permutations = new int[24][4];
permutations[0] = new int[4];
for ( int i = 0; i < numbers.length; i++ ) {
int[][] current = new int[24][4];
for ( int[] permutation : permutations ) {
for ( int j = 0; j < permutation.length; j++ ) {
permutation[j] = numbers[i];
int[] temp = new int[4];
current[i] = temp;
}
}
permutations = current;
}
return permutations;
}
However this returns all zeroes. I chose 24 and 4 because that is the size of the 2D array that I need.
Thanks
It’s not really that easy. The original code exploits the more dynamic behaviour of ArrayList, so a bit of hand coding will be necessary. There are many correct thoughts in your code. I tried to write an explanation of the issues I saw, but it became too long, so I decided to modify your code instead.
The original temp.add(j, numbers[i]); is the hardest part to do with arrays since it invloves pushing the elements to the right of position j one position to the right. In my version I create a temp array just once in the middle loop and shuffle one element at a time in the innermost loop.
public static int[][] permute(int[] numbers) {
// Follow the original here and create an array of just 1 array of length 0
int[][] permutations = new int[1][0];
for (int i = 0; i < numbers.length; i++) {
// insert numbers[i] into each possible position in each array already in permutations.
// create array with enough room: when before we had permutations.length arrays, we will now need:
int[][] current = new int[(permutations[0].length + 1) * permutations.length][];
int count = 0; // number of new permutations in current
for (int[] permutation : permutations) {
// insert numbers[i] into each of the permutation.length + 1 possible positions of permutation.
// to avoid too much shuffling, create a temp array
// and use it for all new permutations made from permutation.
int[] temp = Arrays.copyOf(permutation, permutation.length + 1);
for (int j = permutation.length; j > 0; j--) {
temp[j] = numbers[i];
// remember to make a copy of the temp array
current[count] = temp.clone();
count++;
// move element to make room for numbers[i] at next position to the left
temp[j] = temp[j - 1];
}
temp[0] = numbers[i];
current[count] = temp.clone();
count++;
}
assert count == current.length : "" + count + " != " + current.length;
permutations = current;
}
return permutations;
}
My trick with the temp array means I don’t get the permutations in the same order as in the origianl code. If this is a requirement, you may copy permutation into temp starting at index 1 and shuffle the opposite way in the loop. System.arraycopy() may do the initial copying.
The problem here is that you really need to implement properly the array version of the ArrayList.add(int,value) command. Which is to say you do an System.arraycopy() and push all the values after j, down one and then insert the value at j. You currently set the value. But, that overwrites the value of permutation[j], which should actually have been moved to permutations[j+1] already.
So where you do:
permutation[j] = numbers[i];
It should be:
System.arraycopy(permutation,j, permutations, j+1, permutations.length -j);
permutation[j] = numbers[i];
As the ArrayList.add(int,value) does that. You basically wrongly implemented it as .set().
Though personally I would scrap the code and go with something to dynamically make those values on the fly. A few more values and you're talking something prohibitive with regard to memory. It isn't hard to find the nth index of a permutation. Even without allocating any memory at all. (though you need a copy of the array if you're going to fiddle with such things without incurring oddities).
public static int[] permute(int[] values, long index) {
int[] returnvalues = Arrays.copyOf(values,values.length);
if (permutation(returnvalues, index)) return returnvalues;
else return null;
}
public static boolean permutation(int[] values, long index) {
return permutation(values, values.length, index);
}
private static boolean permutation(int[] values, int n, long index) {
if ((index == 0) || (n == 0)) return (index == 0);
int v = n-(int)(index % n);
int temp = values[n];
values[n] = values[v];
values[v] = temp;
return permutation(values,n-1,index/n);
}
int arr[ ] = new int[3];
for (int i = 0; i < 3; i++) {
arr[i] = i;
}
int res = arr[0] + arr[2];
System.out.println(res);
I'm a beginner in java, as you can see, and I'm not quite sure what's the output of this. Can someone answer and explain along the way?
//if you're using Eclipse, press ctrl-shift-f to "beautify" your code and make it easier to read
int arr[] = new int[3]; //create a new array containing 3 elements
for (int i = 0; i < 3; i++) {
arr[i] = i;//assign each successive value of i to an entry in the array
}
int res = arr[0] + arr[2];//add the 0th element value to the 2nd element value, save in res
System.out.println(res);//print res, which is == 0 + 2
basically what you are doing here is
int arr[ ] = new int[3];
for (int i = 0; i < 3; i++) {
arr[i] = i; // you are adding elements on array location
}
int res = arr[0] + arr[2];
System.out.println(res);
when first time loop execute i equals to 0, on location 0 you are assigning 0 there and for 1,2 the same process is being applied. On line int res = arr[0] + arr[2]; you are adding values of location 0 and 2 which are 0and 2 so the output is 2 when you add 0+2 = 2 in basic mathematics
On the first line, you are creating a new array of integers. The array has the elements arr[0], arr[1], and arr[2].
On the next three lines, is your for loop. As you have written in the loop, it will start from i=0 and will continue running while i < 3. Therefore, i will be 0, 1, and 2. In the loop itself, you are saying:
arr[0] = 0, arr[1] = 1, arr[2] = 2.
On the last two lines, you have two statements. The first expression creates an integer called res. Then you are saying res = arr[0] + arr[2]. But as we just saw, in the for loop you made arr[0] = 0 and arr[2] = 2. Therefore, res = 0 + 2 = 2.
On the last line you are just printing the result in the console.
I am trying to read in a string from a file, extract individual characters and use those characters to fill a 2D char array. So far I have been able to do everything except fill the array. I keep getting an Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: error message. Any help would be appreciated. This is my first time working with 2D arrays. Thanks.
Here are the contents of the test.txt. Each word on a new line. The first 2 integers are the dimensions of the array
4 4
FILE
WITH
SOME
INFO
public class acsiiArt
{
public static void main(String[] args) throws IOException
{
File file = new File("test.txt");
Scanner inputFile = new Scanner(file);
int x = inputFile.nextInt();
int y = inputFile.nextInt();
while (inputFile.hasNext())
{
char [][] array = new char [x][y];
//char c = words.charAt(i);
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
{
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
}
}
}
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
{
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
The total number of indices in array is x * y. Below, you are filling all the possible indices
for (int row =0; row<x;row++)
{
for (int col =0; col<y;col++)
So when you add this:
for (int i=0; i<words.length(); i++)
you multiplying another factor words.length. So you need x * y * words.length number of indices, but you only have x * y. Thats why you're getting ArrayIndexOutOfBoudsException
I've seen problems like this and I'm assuming that x and y are being initialized to the first two characters which represent the number of rows and the number of columns. If that is the case, then third for loop for (int i=0; i<words.length(); i++) is unnecessary. You can just reffer to the col variable for the word at that point, since it should represent how many characters there are.
All of this is only applicable if the chars are in a rectangular pattern, meaning that there are the same number of columns in every row. Otherwise you will get an IndexOutOfBoundsError as soon as one of the lines is shorter than the the column value initially given.
Edit: If you're final 2d char array is not meant to be rectangular and instead "jagged," a different implementation is required. I'd recommend either a 2d arrayList (an arrayList of arrayLists).
Or you can keep your current implementation with the third for loop, but you have to be sure that the original x value represents the longest row/most amount of columns, and then you'd be able to deal with each row indivually with words.length. You'd also have to be fine with the extra portions of the lines that have a length>x having spaces initialized to null.
ArrayIndexOutOfBoundsException means you are using array beyond its limit. So in your case:
char [][] array = new char [x][y];
//char c = words.charAt(i);
for (int row =0; row<x;row++) {
for (int col =0; col<y;col++){
String words = inputFile.nextLine();
for (int i=0; i<words.length(); i++)
array[x][y]=words.charAt(i);
}
}
Problem may be because your array size is less then input words. problem is because you are putting extra loop, and your loop it self is not correct. Please seen code below.
So you can do 2 things.
change value of y large enough so that any word string can store.
rather than looping on size of word you can loop on your array size like.
.
for (int row =0; row<x;row++) {
String words = inputFile.nextLine();
int size = Math.min(words.length(),y);
for (int i=0; i< size; i++)
array[row][i]=words.charAt(i);
}
The easiest way to do this is with an ArrayList<char[]>. All you have to do is add a new char[] for each new line read:
ArrayList<char[]> chars = new ArrayList<>();
while (inputFile.hasNext()){
chars.add(inputFile.nextLine().toCharArray());
}
char[][] array = chars.toArray(new char[chars.size()][]);
An ArrayList is basically an array of changeable size. This code takes each line in the file, turns it into a char[], then adds it to the ArrayList. At the end, it converts the ArrayList<char[]> into a char[][].
If you can't or don't want to use ArrayList, you could always do this:
char[][] array = new char[1][];
int a = 0;
while(inputFile.hasNext()){
//read line and convert to char[]; store it.
array[a] = inputFile.nextLine().toCharArray();
//if there are more lines, increment the size of the array.
if (inputFile.hasNext()){
//create a clone array of the same length.
char[][] clone = new char[array.length][];
//copy elements from the array to the clone. Note that this can be
//done by index with a for loop
System.arraycopy(array, 0, clone, 0, array.length);
//make array a new array with an extra char[]
array = new char[array.length + 1][];
//copy elements back.
System.arraycopy(clone, 0, array, 0, clone.length);
a++;
}
}
If you know the dimensions of the array beforehand:
char[][] array = new char[dimension_1][];
int a = 0;
while (inputFile.hasNext()){
array[a] = inputFile.nextLine().toCharArray();
a++; //don't need to check if we need to add a new char[]
}
In response to comment:
We know that a char[][] cannot be printed with Arrays.toString() (if we want the contents) because we will get a lot of char[].toString(). However, a char[][] can be printed with one of the following methods:
public static String toString(char[][] array){
String toReturn = "[\n";
for (char[] cArray: array){
for (char c: cArray){
toReturn += c + ",";
}
toReturn += "\n";
}
return toReturn + "]";
}
I personally prefer this one (requires import java.util.Arrays):
public static String toString(char[][] array){
String toReturn = "[\n";
for (char[] cArray: array){
toReturn += Arrays.toString(cArray) + "\n";
}
return toReturn + "]";
}
I have a list in a array, each entry either contains o: or g: in front of a word, like o:word or g:word. I want 2 functions, one to make an array with just the g:'s and one to make an array with just the o:'s
I also want the g:'s and o:'s to be pruned out of the result. I'm not sure how to do this without causing array out of bounds errors and such, so I was wondering if someone could give me an example.
Smells like homework.
String[] array = ...
ArrayList<String> gList = new ArrayList<String>();
ArrayList<String> oList = new ArrayList<String>();
for (String word : array) {
if (word != null)) {
if (word.startsWith("g:"))
gList.add(word.subString(2));
else if (word.startsWith("o:")
oList.add(word.subString(2));
}
}
One way is to use ArrayLists to create the new lists. If you need to have primitive arrays after you've got the two new lists, just use toArray() on them.
You would be better off working with ArrayLists (than arrays), because you don't know in advance what size the result will be. But you can make two passes, one to count the rows with the prefix of interest, and a second to populate the new array.
int n = 0;
for (int i = 0; i < array.size; i++)
if (array[i].startsWith(prefix))
n++;
String[] result = new String[n];
int j = 0;
for (int i = 0; i < array.size; i++)
if (array[i].startsWith(prefix))
result[j++] = array[i].substring(prefix.length());
Untried, but I think that ought to do the job.
Assuming that you can mess up the original array, and that you don't need to preserve the order, this should be quite fast:
String[] array = {"o:1","o:2","g:10","o:3","g:20","o:4","g:30","g:40","o:5"};
int low = 0;
int high = array.length - 1;
while(low <= high) {
if(array[low].startsWith("g:")) {
array[low] = array[low].substring(2);
low ++;
} else if (array[high].startsWith("o:")) {
array[high] = array[high].substring(2);
high --;
} else {
String temp = array[low].substring(2);
array[low] = array[high].substring(2);
array[high] = temp;
low++;
high--;
}
}
String[] gs = new String[low];
System.arraycopy(array, 0, gs, 0, low);
String[] os = new String[array.length - low];
System.arraycopy(array, low, os, 0, array.length - low);