问题
I am working on an assignment, and I can't find a way to make this work properly. I have an ArrayList with information on 5 students. I need to construct a method that will remove one of the objects, but I do not need/want iteration, as it is a static removal. I have the following code:
import java.util.ArrayList;
import java.lang.String;
public class Roster {
static ArrayList<Student> myRoster = new ArrayList<>();
public static void main(String[] args){
//Add Student Data
Roster.add("1","John","Smith");
add("2","Suzan","Erickson");
add("3","Jack","Napoli");
add("4","Erin","Black");
add("5","Jason","Rapp");
remove("3");
remove("3");
}
public static void add(String studentID, String fName, String lName){
Student newStudent = new Student(studentID, fName, lName);
myRoster.add(newStudent);
}
public static void remove(String studentID){
if (myRoster.contains(studentID)){
Roster.remove(studentID);
}
else {
System.out.println("This student ID does not exist.");
}
}
When I compile the code, none of the entries are removed, and the else
statement fires off for both remove
calls.
回答1:
myRoster
is a List
of Student
objects. List
contains
and remove
will work against only like objects, not String
values - it has no idea how to match a String
against a Student
.
As an alternative, you could make use of List
's Stream
support and filter
the List
for elements which match the studentID
and then remove all those elements, for example...
public static void remove(String studentID) {
List<Student> matches = myRoster.stream().filter(student -> student.getStudentID().equals(studentID)).collect(Collectors.toList());
myRoster.removeAll(matches);
}
but I do not need/want iteration
Just so you understand, there is still an iteration been performed, it's just that you're not doing it yourself, the API is
回答2:
It sounds as though perhaps you should be using a map rather than a list, e.g.
Map<Integer, Student> sMap = new HashMap<>();
sMap.put(1, new Student("1", "John","Smith"));
sMap.put(2, new Student("2", "Suzan","Erickson"));
sMap.put(3, new Student("3", "Jack","Napoli"));
sMap.put(4, new Student("4", "Erin","Black"));
sMap.put(5, new Student("5", "Jason","Rapp"));
Then, if you need to remove a student from the map, you can use the following one liner:
sMap.remove(3);
回答3:
ArrayList.contains(Object)
and .remove(Object)
uses Object.equals
to iterate the whole list and find the object. So
- If you insist using
ArrayList
, you should override theequals
method ofStudent
, and thehashCode
method too, making them usestudentId
only. You should also modify theRoster.remove
method, making it callmyRoster.contains
instead of calling itself again. - Below the surface it still is iterate.
回答4:
Going off of MadProgrammer's answer, there is no reason to open your own stream to collect students to remove when you can call Collection's removeIf
myRoster.removeIf(s -> studentID.equals(s.getstudentID()));
来源:https://stackoverflow.com/questions/49524813/removing-from-java-arraylist-without-iteration