0

I have seen you can do this using ArrayLists, but is it possible to do this using a normal object array?

deleting an object from an array [java]

At the start of each the player is given 3 random dice from a cup.

The cup has 13 dice in total.

When the player is given the 3 dice from the cup the cup should have only 10 dice in left. I was trying to set the value to null but this still counts as a index in the array so the length does not change.

// Removing the 3 dice which were picked form the cup of the current player, the diceToTakeOut is a String array with a length of 3 the newTurnCup is a Object array with a length of 13
public static Dice [] cup(String [] diceTotakeOut, Dice [] newTurnCup){

    for (int i = 0; i < diceTotakeOut.length; i++) {

        if (diceTotakeOut.length > 0) {
            if (diceTotakeOut[i] == newTurnCup[i].getName()) {
                newTurnCup[i] = null;
            }
        }
    }

    return newTurnCup;
}

I have tried a few different ways which I could think of:

newTurnCup[i] = null;

newTurnCup[i] = newTurnCup[i - 1];

The result would be after each turn the array holding the dice would have 3 index less.

Andrew Regan
  • 5,087
  • 6
  • 37
  • 73
Liam
  • 568
  • 2
  • 15
  • 1
    As the linked question says: No. An array has a fixed size. Is there a reason you don’t want to use a List or other collection? – VGR Sep 10 '19 at 14:35
  • @VGR, Not really I am doing a Computer Science course and they teach the long way of doing things ie. without using methods. I was just wondering for my own knowledge is it possible – Liam Sep 10 '19 at 14:37
  • 1
    I am not sure what you *really* want to accomplish but quick answer is: no, in Java arrays have fixed size so no *index* can be removed (you can only change content which is held at that index). Anyway based on `diceTotakeOut[i] == newTurnCup[i].getName()` you may be comparing strings here. In that case instead of `str1 == str2` you should be using `str1.equals(str2)` as explained in [How do I compare strings in Java?](https://stackoverflow.com/q/513832). – Pshemo Sep 10 '19 at 14:37
  • If I understood what you're trying to achieve, I think you're talking about shifting the content, the element at index `i` will not be removed but from that index to the end, all elements will receive the content of the next one, `(i + 1) --> i` – XBlueCode Sep 10 '19 at 14:47

7 Answers7

2

It's not doable since the array has a fixed size.

But try using an ArrayList which allow you to remove elements dynamically using the method remove(int index)

or:

shift the content of the array starting from the targeted index to the end. (shift: left to right).

XBlueCode
  • 785
  • 3
  • 18
1

You can't do this cleanly with an array; you would have to recreate a shorter array every time.

You can do it with other data structures, for example a LinkedList.

Adder
  • 5,708
  • 1
  • 28
  • 56
1

You can't do that. In Java an array is an immutable object. Once created, the size of this array cannot be changed (sure you could modify array items).

To have a collection with the various size you should use List collection: ArrayList - this is based on an internal array with additional property - size, LinkedList.

List<Dice> dices = new ArrayList<>();   // dices.size() -> 0
dices.add(null);    // dices.size() -> 1    
dices.add(null);    // dices.size() -> 2
dices.remove(0);    // dices.size() -> 1

To make array immutability clear, this is an example of how manually remove an item from an array:

public static Dice[] removeItem(Dice[] dices, int i) {
    if (dices == null || dices.length == 0)
        return dices;
    if (i < 0 || i >= dices.length)
        throw new ArrayIndexOutOfBoundsException();

    Dice[] res = new Dice[dices.length - 1];
    System.arraycopy(dices, 0, res, 0, i);
    System.arraycopy(dices, i + 1, res, i, dices.length - i - 1);
    return res;
}

Dice[] arr = null;
arr = removeItem(arr, 5);
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
1

Since you are working with array and not ArrayList, you can achieve this by creating a work around.

public static Dice[] removeTheElement(Dice[] arr, int index) { 

    // If the array is empty 
    // or the index is not in array range 
    // return the original array 
    if (arr == null
        || index < 0
        || index >= arr.length) { 

        return arr; 
    } 

    // Create another array of size one less 
    Dice[] anotherArray = new Dice[arr.length - 1]; 

    // Copy the elements except the index 
    // from original array to the other array 
    for (int i = 0, k = 0; i < arr.length; i++) { 

        // if the index is 
        // the removal element index 
        if (i == index) { 
            continue; 
        } 

        // if the index is not 
        // the removal element index 
        anotherArray[k++] = arr[i]; 
    } 

    // return the resultant array 
    return anotherArray; 
} 

So in here, we pass as a parameter the Object that we are working with, and the index of the array that we like to remove. We create a temporary Object inside to our function and return it without the element with the index number that we provided.

Rich
  • 3,928
  • 4
  • 37
  • 66
1

An array variable in Java is a pointer to a zone of memory directly proportionate to it's capacity and the size of the type it contains. This area cannot be dynamically modified. The only way to do what you want is to create a new array variable that has allocated the new size of array you want. This is what happens behind the scenes also in the Collections that implement this functionality just that there are optimisations in place in order to do this (potentially very costly) operations only when it is needed.

So my best suggestion would be to change your design to use Lists, ArrayLists for example. LinkedLists, althought they came out as a nice idea, in practice are generally avoided because they are in fact slower (they don't take advantage of hardware memory caching).

wi2ard
  • 1,471
  • 13
  • 24
  • Thanks for the information, do you mean professional programmers avoid using Lists because they are slow? Or that creating a new array with the desired length is slow? – Liam Sep 10 '19 at 14:52
  • I meant avoid using LinkedList and avoid "reinventing the wheel" - in this case this manipulation of memory for collections is already implemented at tested in JDK and it is usually unlikely you need to improve that – wi2ard Sep 10 '19 at 15:01
1

As mentioned in other answers, you cannot remove an element from an array directly. You need to write a custom method which will copy all the elements except the one which you need to remove.

However, I suggest you should use ArrayUtils from Apache Commons.

ArrayUtils.remove(array, index)

Some examples from the docs:

ArrayUtils.remove(["a", "b"], 0)      = ["b"]
ArrayUtils.remove(["a", "b"], 1)      = ["a"]

Refer: ArrayUtils Documentation

Govinda Sakhare
  • 5,009
  • 6
  • 33
  • 74
0

Your best bet is to use ArrayList and then after manipulating getting array out of it.

If you want to get your hands dirty and are accepting that you have to create new array, you can do the following:

private static String[] removeIndex(String[] inputArray, int indexToRemove){
    if (indexToRemove >= inputArray.length) {
        throw new IndexOutOfBoundsException("index "  + indexToRemove + " is not allowed for array with size=" + inputArray.length);
    }
    String[] resultArray = new String[inputArray.length - 1 ];
    System.arraycopy(inputArray, 0, resultArray, 0, indexToRemove);
    System.arraycopy(inputArray, indexToRemove + 1, resultArray, indexToRemove, resultArray.length - indexToRemove);

    return resultArray;
}

And then consuming it:

String[] inputArray = new String[]{"1","2","3","4","5","6","7","8","9","10"};

System.out.println(Arrays.toString(removeIndex(inputArray, 0)));
System.out.println(Arrays.toString(removeIndex(inputArray, 1)));
System.out.println(Arrays.toString(removeIndex(inputArray, 2)));
System.out.println(Arrays.toString(removeIndex(inputArray, 3)));
System.out.println(Arrays.toString(removeIndex(inputArray, 4)));
System.out.println(Arrays.toString(removeIndex(inputArray, 5)));
System.out.println(Arrays.toString(removeIndex(inputArray, 6)));
System.out.println(Arrays.toString(removeIndex(inputArray, 7)));
System.out.println(Arrays.toString(removeIndex(inputArray, 8)));
System.out.println(Arrays.toString(removeIndex(inputArray, 9)));
System.out.println(Arrays.toString(removeIndex(inputArray, 10)));

produces:

[2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Exception in thread "main" java.lang.IndexOutOfBoundsException: index 10 is not allowed for array with size=10
at Scratch.removeIndex(scratch.java:81)
at Scratch.main(scratch.java:73)
diginoise
  • 7,352
  • 2
  • 31
  • 39