从对象本身确定Object在数组中的索引

时间:2013-03-24 02:16:58

标签: java arrays

数组中的对象是否有办法检测它们所在的插槽?如果我有一个Object数组,那么数组中的Object是否可以在没有明确告知的情况下检测它所在的单元格?

4 个答案:

答案 0 :(得分:2)

不幸的是,不,数组在Java中的工作方式是数组只是“指向”一个对象。由于Java数组只存储引用(对象),但任何数量的变量都可以引用同一个对象,因此Object不知道它在数组中的位置。实际上,可以从数组中的几个索引指向同一个对象!

考虑

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.

希望这有帮助!

迭代对象数组的最快(最容易编写)的方法是

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

答案 1 :(得分:2)

没有。如果你需要这样做,你可能有一个设计缺陷。为什么Object需要知道数组中出现的位置?如果索引具有对象的某些语义或感兴趣,则该对象应具有包含此信息的int字段。如果你试图根据一个对象修改原始数组,那么你可能在某处有一个很差的类,例如如果发生这样的事情:

class A {
    Object data[];
}

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

然后真的B.remove应该是A的方法,因此首先可以访问data。等等。

此外,数组可能不是正确的数据结构。如果索引具有很大的语义值,Map<Integer, Object>可能更合适,尽管当索引从1..n连续并且数组是不可变的时,数组通常用于表示它。在我remove的愚蠢示例中,List会更合适。等

答案 2 :(得分:1)

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

答案 3 :(得分:0)

正如@Aaron_H所说,没有骰子。我补充一点,你可以解决这个问题:

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;
    }    
}