Java中如何在ArrayList中查找对象?泛型代码实现指南
Alright, let's figure out how to implement the find and find2 methods for searching a specific Box object in an ArrayList within your Generics class. I'll break this down with full code examples and explanations so you can follow along easily.
First, let's set up the necessary context. We'll start with the Box generic class, since your Generics class stores instances of this. It's crucial to override equals() (and hashCode(), as a best practice) here because we need to compare the content of Box objects, not just their memory references.
Step 1: Define the Box Generic Class
public class Box<T> { private T content; public Box(T content) { this.content = content; } public T getContent() { return content; } // Override equals to compare content instead of object references @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Box<?> box = (Box<?>) o; return content != null ? content.equals(box.content) : box.content == null; } // Always override hashCode when overriding equals (best practice) @Override public int hashCode() { return content != null ? content.hashCode() : 0; } }
Step 2: Complete the Generics Class with find and find2 Methods
Now we'll implement the two search methods. The find method uses a traditional loop, while find2 leverages Java 8+ Stream API for a more modern, concise approach.
import java.util.ArrayList; import java.util.List; import java.util.Optional; public class Generics<T> { private List<Box<T>> boxList = new ArrayList<>(); // Helper method to add Box instances for testing public void addBox(Box<T> box) { boxList.add(box); } // Method 1: Traditional loop to find the first matching Box, returns null if not found public Box<T> find(Box<T> target) { for (Box<T> box : boxList) { // Uses our overridden equals method to check for matching content if (box.equals(target)) { return box; } } return null; } // Method 2: Stream API approach, returns Optional<Box<T>> for safer null handling public Optional<Box<T>> find2(Box<T> target) { return boxList.stream() .filter(box -> box.equals(target)) .findFirst(); } // Test the implementation public static void main(String[] args) { Generics<String> stringGenerics = new Generics<>(); stringGenerics.addBox(new Box<>("Apple")); stringGenerics.addBox(new Box<>("Banana")); stringGenerics.addBox(new Box<>("Orange")); // Test find method Box<String> bananaTarget = new Box<>("Banana"); Box<String> foundBox = stringGenerics.find(bananaTarget); if (foundBox != null) { System.out.println("find() found: " + foundBox.getContent()); } else { System.out.println("find() didn't find the target"); } // Test find2 method with a non-existent target Box<String> grapeTarget = new Box<>("Grape"); stringGenerics.find2(grapeTarget).ifPresentOrElse( box -> System.out.println("find2() found: " + box.getContent()), () -> System.out.println("find2() didn't find the target") ); } }
Key Explanations
- Why override equals()? The default
equals()method compares object references, which means twoBoxinstances with the same content would be considered different unless they're the exact same object. Our overridden method checks if the content matches instead, which is what we want for a meaningful search. - find() method: This is a straightforward iterative approach—loop through each element, check for a match, and return the first hit. If no match is found, it returns
null. - find2() method: Using Streams makes the code more readable, and returning an
Optionalavoids null pointer exceptions. You can safely handle the "not found" case using methods likeifPresentOrElse()ororElse()instead of checking fornull.
Notes
If your existing Box class already has a properly implemented equals() method, you can skip that part. Just make sure it's comparing the content you care about for the search.
内容的提问来源于stack exchange,提问作者Mister M

