Java中ArrayList存储对象及indexOf查找返回-1问题技术咨询
indexOf("max...") Returns -1 for Your ArrayList of Custom Objects First, let's look at your original code for context:
public static void test(){ ArrayList<mainclass> zbor = new ArrayList<>(); mainclass l2c = null; for (int i=0;i<2;i++){ l2c = new mainclass(); System.out.println("name"); l2c.name = user_input.nextLine(); System.out.println("surname"); l2c.sname = user_input.nextLine(); zbor.add(l2c); } System.out.println("===1===="); System.out.println(zbor); System.out.println("===2===="); for (int i=0;i<zbor.size();i++) { System.out.println(zbor.get(i)); } int index_search = zbor.indexOf("max..."); }
The Root Cause
The indexOf() method in ArrayList works by iterating through the collection and using the equals() method to compare the argument you pass with each element in the list.
Here's the problem: you're passing a String ("max...") to search for, but your zbor list stores mainclass objects. The default equals() implementation (inherited from Object) only returns true if the two objects are the same instance—a String can never be the same instance as a mainclass object, so indexOf will always return -1 here.
How to Fix It
You have a few solid options depending on your needs:
1. Override equals() and hashCode() in mainclass
If you want indexOf() to work with a value (like a name) instead of object references, you need to define what makes two mainclass objects "equal" by overriding these methods. For example, if you want to match by the name field:
import java.util.Objects; class mainclass { String name; String sname; @Override public boolean equals(Object o) { // Check if it's the same instance first if (this == o) return true; // Check if the object is null or not the same class if (o == null || getClass() != o.getClass()) return false; // Cast to mainclass and compare the name field mainclass mainclass = (mainclass) o; return Objects.equals(name, mainclass.name); } @Override public int hashCode() { // Always override hashCode when you override equals return Objects.hash(name); } }
Then, to search for a mainclass with name "max...", you need to pass a mainclass instance with that name to indexOf:
mainclass searchObj = new mainclass(); searchObj.name = "max..."; int index_search = zbor.indexOf(searchObj);
2. Manually Iterate to Find the Index
If you don't want to override equals(), you can loop through the list and check each object's properties directly:
int index_search = -1; for (int i = 0; i < zbor.size(); i++) { mainclass obj = zbor.get(i); if ("max...".equals(obj.name)) { // Use equals() to avoid NPE if name is null index_search = i; break; // Stop searching once found } }
3. Use Java Streams (Java 8+)
For a more concise approach, you can use streams to find the index:
import java.util.OptionalInt; import java.util.stream.IntStream; // ... OptionalInt indexOpt = IntStream.range(0, zbor.size()) .filter(i -> "max...".equals(zbor.get(i).name)) .findFirst(); // Get the index, or -1 if not found int index_search = indexOpt.orElse(-1);
Key Takeaways
indexOf()relies entirely on theequals()method to match elements.- Comparing different types (String vs. your custom object) will always fail with the default
equals()implementation. - Choose the approach that fits your use case: overriding
equals()is best if you'll be comparing objects frequently, while manual iteration or streams are better for one-off searches.
内容的提问来源于stack exchange,提问作者Vital Iliic

