Determine index from array reference?

K

Knute Johnson

Is there a way to determine the index of an array element given a reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,
 
J

Jason Cavett

Is there a way to determine the index of an array element given a reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,

Not to my knowledge. This is why Collection classes were made, though.
Many of the Collection classes offer a method that gives you the index
based on the Object. (I believe it's indexOf(Object object) without
looking up Javadocs.)
 
K

Knute Johnson

Jason said:
Is there a way to determine the index of an array element given a reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,

Not to my knowledge. This is why Collection classes were made, though.
Many of the Collection classes offer a method that gives you the index
based on the Object. (I believe it's indexOf(Object object) without
looking up Javadocs.)

I hadn't really considered it but I guess a Vector would do that nicely.

Thanks,
 
D

Daniel Pitts

Is there a way to determine the index of an array element given a reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,
Arrays.asList(array).indexOf(o);

Anyway, don't use Vector, use ArrayList
 
M

Mike Schilling

Knute Johnson said:
Is there a way to determine the index of an array element given a
reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values of
obj[] and testing for equality of the reference?

You could call

Array.asList(obj).indexOf(q)

But all that does is hide the code that iterates through the array. And
note that it checks for object equality, not reference equality. (i.e.
o.equals(p), not o == p)
 
M

Mark Rafn

Knute Johnson said:
Is there a way to determine the index of an array element given a reference?

Other than searching the array, no. And you don't buy anything by converting
it to a Vector or other List and calling indexOf(), because THAT just does a
search after a bunch of copying.

Object[] obj = new Object[8];
Object q = obj[2];
Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

In your example q will be null, which will be the value at ALL indices of the
array. This is possible even for a populated array. for example:

String[] strings = new String[] { "a", "b", "c", "a", "a", "a" };
String aString = strings[3];

The object pointed to by the variable aString is also pointed to by positions
0, 3, 4, and 5 of the array.
 
P

Patricia Shanahan

Knute said:
Is there a way to determine the index of an array element given a
reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,

This type of question always seems a little backwards to me. I tend to
think the other way round. Not "How do I do this with an array?" but "I
need to do these accesses. What data structure should I use?".

Why an array? What other operations are being done on it?

Patricia
 
K

Knute Johnson

Patricia said:
Knute said:
Is there a way to determine the index of an array element given a
reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,

This type of question always seems a little backwards to me. I tend to
think the other way round. Not "How do I do this with an array?" but "I
need to do these accesses. What data structure should I use?".

Why an array? What other operations are being done on it?

Patricia

Thanks everybody for your replies. And since Patricia asked the big
question maybe I should give up some more information about what exactly
I'm trying to do.

I asked about an array because that's what I have now. An array of
JTextFields that have ActionListeners attached. In the AL I need to
update another array. So what I had done in the past was to extend
JTextField and add an int variable to hold an index value for the
JTextField. I added a getIndex() method and in my ActionListener I use
that method to acquire the index to modify my other array.

So I could have checked the JTextField reference against all the others
in the array and gotten an index that way but that didn't sound a whole
lot better than the way I was getting it now.

The little program below appears to work with a Vector. What do you
think of that approach?

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class test1 {
public static void main(String[] args) {
Vector<JTextField> v = new Vector<JTextField>();
JTextField test = null;

for (int i=0; i<10; i++) {
JTextField tf = new JTextField(" ",10);
v.add(tf);
if (i == 3)
test = tf;
}

System.out.println(v.indexOf(test));
System.out.println(v.indexOf(null));
}
}

Anyway, if anybody has a better idea I'm all ears.

Thanks,
 
L

Lew

Knute said:
I asked about an array because that's what I have now. An array of
JTextFields that have ActionListeners attached. In the AL I need to
update another array. So what I had done in the past was to extend
JTextField and add an int variable to hold an index value for the
JTextField. I added a getIndex() method and in my ActionListener I use
that method to acquire the index to modify my other array.

So I could have checked the JTextField reference against all the others
in the array and gotten an index that way but that didn't sound a whole
lot better than the way I was getting it now.

That is exactly what your posted code does.
The little program below appears to work with a Vector. What do you
think of that approach?

Why ignore the advice to use ArrayList?
public class test1 {
public static void main(String[] args) {
Vector<JTextField> v = new Vector<JTextField>();
JTextField test = null;

for (int i=0; i<10; i++) {
JTextField tf = new JTextField(" ",10);
v.add(tf);
if (i == 3)
test = tf;
}

System.out.println(v.indexOf(test));
System.out.println(v.indexOf(null));
}
}

Bear in mind that these are first occurrences of these values in the List.

If you plan to use the result of your "indexOf()" to locate another object,
rather than just println() it, you might consider using a
Map <JTextField, OtherType>. That would have the benefit of constant time
lookup (if you use HashMap) instead of O(n). You also avoid bugs caused by
"parallel" Lists going non-Euclidean.

- Lew
 
K

Knute Johnson

Daniel said:
Is there a way to determine the index of an array element given a reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,
Arrays.asList(array).indexOf(o);

Anyway, don't use Vector, use ArrayList

What's wrong with Vector?
 
K

Knute Johnson

Lew said:
Why ignore the advice to use ArrayList?

What's the aversion to Vector?
public class test1 {
public static void main(String[] args) {
Vector<JTextField> v = new Vector<JTextField>();
JTextField test = null;

for (int i=0; i<10; i++) {
JTextField tf = new JTextField(" ",10);
v.add(tf);
if (i == 3)
test = tf;
}

System.out.println(v.indexOf(test));
System.out.println(v.indexOf(null));
}
}

Bear in mind that these are first occurrences of these values in the List.

Well there shouldn't be other occurrences or it won't work at all.
If you plan to use the result of your "indexOf()" to locate another
object, rather than just println() it, you might consider using a
Map <JTextField, OtherType>. That would have the benefit of constant
time lookup (if you use HashMap) instead of O(n). You also avoid bugs
caused by "parallel" Lists going non-Euclidean.

- Lew

I don't think that saves me anything over the original scheme and just
makes it more complicated.
 
L

Lew

Knute said:
I don't think that saves me anything over the original scheme and just
makes it more complicated.

It doesn't save anything except time, memory and the likelihood of bugs.

- Lew
 
R

Remon van Vliet

Knute Johnson said:
Daniel said:
Is there a way to determine the index of an array element given a
reference?

Object[] obj = new Object[8];

Object q = obj[2];

Is it possible to get 2 from q other than iterating through all values
of obj[] and testing for equality of the reference?

Thanks,
Arrays.asList(array).indexOf(o);

Anyway, don't use Vector, use ArrayList

What's wrong with Vector?

All Vector methods are synchronized, so unless that's a necessity for you
it's unnecessary overhead. Vector does implement Collection and Sun
considers it part of the JCF but it's atypical compared to the newer
Collection classes, as such Collections.synchronizedList(new ArrayList()) is
a more fitting alternative for the same fuctionality.

Remon
 
C

Chris Uppal

Knute said:
So I could have checked the JTextField reference against all the others
in the array and gotten an index that way but that didn't sound a whole
lot better than the way I was getting it now.

As a matter of general design, avoid maintaining more than one independent copy
of the same information unless there's a good reason to do so (normally some
sort of performance and/or robustness consideration). That's rather a
fundamental design principle, and applies to all software (and other systems,
come to that).

In this case you have the information about the index of each element stored in
two places: as part of the structure of the array (you could find the index
with a loop); and in the instance field of the (otherwise unnecessary, I
presume) subclass of JTextField. That won't cause a lot of damage in this
particular case (especially if the indexes never change), but it's rather a
baroque arrangement all the same, and as you gain more experience as a designer
you will learn to avoid such constructions where possible.

-- chris
 
K

Knute Johnson

Lew said:
It doesn't save anything except time, memory and the likelihood of bugs.

- Lew

I'm not sure how it can be faster but without testing it I can't be
sure. As to memory, a Map with two objects can't use much less memory
than an int and a get method but so what. Also how would you find the
key with a map? How is it going to be less buggy?
 
K

Knute Johnson

Chris said:
As a matter of general design, avoid maintaining more than one independent copy
of the same information unless there's a good reason to do so (normally some
sort of performance and/or robustness consideration). That's rather a
fundamental design principle, and applies to all software (and other systems,
come to that).

In this case you have the information about the index of each element stored in
two places: as part of the structure of the array (you could find the index
with a loop); and in the instance field of the (otherwise unnecessary, I
presume) subclass of JTextField. That won't cause a lot of damage in this
particular case (especially if the indexes never change), but it's rather a
baroque arrangement all the same, and as you gain more experience as a designer
you will learn to avoid such constructions where possible.

-- chris

So you vote for looping through the array until a match is found?

Thanks,
 
K

Knute Johnson

Chris said:
As a matter of general design, avoid maintaining more than one independent copy
of the same information unless there's a good reason to do so (normally some
sort of performance and/or robustness consideration). That's rather a
fundamental design principle, and applies to all software (and other systems,
come to that).

In this case you have the information about the index of each element stored in
two places: as part of the structure of the array (you could find the index
with a loop); and in the instance field of the (otherwise unnecessary, I
presume) subclass of JTextField. That won't cause a lot of damage in this
particular case (especially if the indexes never change), but it's rather a
baroque arrangement all the same, and as you gain more experience as a designer
you will learn to avoid such constructions where possible.

-- chris

Just another question. Would you still think that if the array were
huge, hundreds of thousands or millions of elements?

Thanks again,
 
M

Mark Rafn

Winner! Keeping parallel lists or arrays, and searching one to find the index
in another is error-prone, hard-to-understand, and makes you look like a
non-OO neanderthal programmer. The first two are actually good reasons to
consider alternatives, and the third is a gratuitous epithet which may provide
a bit of motivation to change, or to explain things well enough to know why
it doesn't apply in this case.

Knute Johnson said:
I don't think that saves me anything over the original scheme and just
makes it more complicated.

how is
OtherType thing = fieldMap.get(thisField)
more complicated than
OtherType thing = secondArray[Arrays.asList(firstArray).indexOf(thisField)]

It's just more sane to use actual data structures that do what you need than
to sling around pairs of arrays that your code happens to know are in sync.

It's also faster, if these lists get to be of any significant size.
ArrayList.indexOf() is a linear search of the list. HashMap.get() is
constant-time.
 
L

Lew

Knute said:
I'm not sure how it can be faster but without testing it I can't be
sure.

It's faster because lookups into a HashMap are O(1) and lookups into an
ArrayList are O(n) on the size of the collection. Plus you skip the code to
derive an index then use it to do the lookup in the parallel list.
As to memory, a Map with two objects can't use much less memory
than an int and a get method but so what.

It can use less memory when there are two or more lists coordinated in
parallel, which was the condition under which I suggested using a Map would be
worthwhile.
Also how would you find the key with a map?

Given that you were looking up an index with a JTextField as the key, then
using the index to find a SomeOtherThing, you already have the key - the
JTextField - so there is no lookup of the key, only of the SomeOtherThing
associated with the key.

The suggestion of a Map is predicated on the notion that you are doing that
kind of parallel lookup.
How is it going to be less buggy?

By preventing any bugs caused by independent Lists falling out of synchrony
with each other. With two Lists, the orders or lengths might differ. (This
type of thing has been a question on these newsgroups before.) With a Map, if
the key is in there, so is the value (which might be null). No chance of the
order or length differing, hence less opportunity for bugs.

- Lew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top