David
David

Reputation: 282

Determine index an Object is in an array from the object itself

Is there a way for objects inside an array to detect what slot they are in? If I had a Object array, could a Object inside the array detect what cell it is in without being explicitly told?

Upvotes: 3

Views: 456

Answers (4)

Aaron_H
Aaron_H

Reputation: 1683

Nope, unfortunately, how arrays work in Java is that the array simply "points" to an object. As a Java array only stores references (to objects), but any number of variables can reference the same object, so an Object has no idea where it lives in an array. In fact, the same object can be pointed to from several indices in the array!

Consider

Object o = new Object(); // The variable o has a "reference" to the Object in memory
Object[] arr = new Object[3]; // empty array to hold Object types
arr[0] = o; // the first index points to the Object we created above
arr[1] = o; // the second index points to that same object!
arr[2] = o; // still the same object! If we modified the original object (assuming it's not immutable) in any way, all the indices in this array would point to the modified object.

Hope this helps!

The fastest (easiest to write) way to iterate through an array of objects is

for (Object o : arr) {
    // do something to the local variable o, which you can think of as representing each object in your array
}

Upvotes: 2

djechlin
djechlin

Reputation: 60848

No. If you need to do this, you probably have a design flaw. Why does an Object need to know where it appears in the array? If the index is of some semantic meaning or interest to the object, then the object should have an int field containing this information. If you are trying to modify the original array based on one object then you probably have a poorly-factored class somewhere, e.g. if something such as this is happening:

class A {
    Object data[];
}

class B {
    remove(A a, Object instance) {
        // how to remove instance from a.data??
    }
}

Then really B.remove should be a method of A and hence have access to data in the first place. And so forth.

Furthermore an array may just not be the right data structure. If the index has much semantic value a Map<Integer, Object> may be more appropriate, although arrays are often used to represent this when the indices are continuous from 1..n and the array is immutable. In my silly example with remove, a List would be more appropriate. Etc.

Upvotes: 2

Gene
Gene

Reputation: 47020

As @Aaron_H said, no dice. I'll add that you can work around it with something like this:

public class Test {

    public static void main(String[] args) {
        ZenArray<IndexedString> z = new ZenArray(10);
        for (int i = 0; i < z.size(); i++) {
            z.set(i, new IndexedString("String " + i));
        }
        for (int i = 0; i < z.size(); i++) {
            System.out.println("I'm at index " + z.get(i).getIndex());
        }
    }
}

class ZenArray<T extends ZenArray.IndexedElement> {

    private Object [] a;

    interface IndexedElement {
        void setIndex(int i);
        int getIndex();
    }

    public ZenArray(int size) {
        a = new Object[size];
    }

    public void set(int i, T val) {
        val.setIndex(i);
        a[i] = val;
    }

    public T get(int i) {
        return (T)a[i];
    }

    public int size() {
        return a.length;
    }
}

// An example of an indexed element implementation.
class IndexedString implements ZenArray.IndexedElement {

    int i;
    String val;

    public IndexedString(String val) {
        this.val = val;
    }

    public String getVal() {
        return val;
    }

    @Override
    public void setIndex(int i) {
        this.i = i;
    }

    @Override
    public int getIndex() {
        return i;
    }    
}

Upvotes: 0

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136162

try

    int i = Arrays.asList(arr).indexOf(obj);

Upvotes: 1

Related Questions