Reputation: 3
I want to create a program which would be like a home budget, so I have a class AmountModel
(I know that Integer
is not so good for id, but it's not a problem now):
import java.time.LocalDate;
public class AmountModel {
private Integer id;
private Double amount;
private CategoryModel categoryModel;
private LocalDate localDate;
// getters/setters etc.
}
And in another class I built this deleteAmount
method:
static Scanner sc = new Scanner(System.in);
public List<amountModel> deleteAmount() {
Iterator<AmountModel> it = amountList.iterator();
while (it.hasNext()) {
System.out.println("Choose index to delete ");
AmountModel am = it.next();
if (am.getId().equals(sc.nextInt())) {
it.remove();
}
break;
}
return amountList;
}
Adding object works good, but when I try to use the delete method I have to put first index.
Example:
I have three objects (with index 0, 1, 2).
What is wrong with this method?
Upvotes: 0
Views: 108
Reputation: 596
Welcome to Stack Overflow!
As others have mentioned, there are a few ways to tackle this. But I think you can make this even simpler by changing the data structure used to access your AmountModel
collection: if you're frequently accessing an item by ID, a Map
is a great fit.
No more worrying about iterator state; you could just do something like:
// Map "amounts" by ID for easy O(1) lookup.
static Map<Integer, AmountModel> amountMap
public void deleteAmount(Integer id) {
if (!amountMap.containsKey(id)) {
// (TODO: Handle invalid input)
throw new Exception()
}
amountMap.remove(id)
return
}
Hope this helps! I threw together a working example in a gist here if you're interested. (In Groovy, but should be enough to give you the idea)
Upvotes: 1
Reputation: 26
Your break statement is breaking the while loop in the first iteration only. So, it will work only if the first am.getId() matches with your fist input. Also, your sc.nextInt() will keep on scanning for next available input, Remove it from while loop.
static Scanner sc = new Scanner(System.in);
public List<AmoutModel> deleteAmount() {
Iterator<AmoutModel> it = amountList.iterator();
Integer scId = sc.nextInt();
while (it.hasNext()) {
System.out.println("Choose index to delete ");
AmoutModel am = it.next();
if (am.getId().equals(scId)) {
it.remove();
break;
}
}
return amountList;
}
Upvotes: 0
Reputation: 1760
You should separate your input logic from your delete logic and accept the list as a parameter.
Note: this only works with a mutable list. If you use something like Arrays.asList() it will throw an exception.
public void deleteAmount(List<AmountModel> list, int key) {
list.removeIf(a -> a.getId().equals(key));
}
Upvotes: 1
Reputation: 312
call your sc.nextInt() outside of the loop, otherwise it will get run everytime the loop returns, as the condition gets reevaluated every time the loop ends. also you could use the remove method of list
static Scanner sc = new Scanner(System.in);
public List<AmoutModel> deleteAmount() {
System.out.println("Choose index to delete ");
int index = sc.nextInt();
amountList.remove(index);
return amountList;
}
Upvotes: -1