#Need help working out how to remove a specific type of item from a list/iterator
135 messages · Page 1 of 1 (latest)
⌛ This post has been reserved for your question.
Hey @lilac canyon! Please use
/closeor theClose Postbutton above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
public void consumeResource(ResourceType type, int amount)
throws InsufficientResourcesException {
if (type != ResourceType.REPAIR_KIT) {
throw new IllegalArgumentException();
}
int totalResource = getTotalAmountByType(type);
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> resourceContainers = getResourceByType(type).iterator();
int consumed = 0;
int toBeRemoved = 0;
while (consumed < amount) {
ResourceContainer resourceContainer = resourceContainers.next();
consumed += resourceContainer.getAmount();
toBeRemoved += 1;
}
Iterator<ResourceContainer> containers = this.resources.iterator();
int removed = 0;
while (removed < toBeRemoved) {
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
containers.remove();
removed += 1;
}
}
}
}
public void consumeResource(FuelGrade grade, int amount)
throws InsufficientResourcesException {
int totalFuel = getTotalAmountByType(grade);
if (amount > totalFuel) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> fuelContainers = getResourceByType(grade).iterator();
int consumed = 0;
int toBeRemoved = 0;
while (consumed < amount) {
FuelContainer fuelContainer = (FuelContainer) fuelContainers.next();
consumed += fuelContainer.getAmount();
toBeRemoved += 1;
System.out.println(consumed + " " + toBeRemoved + " " + this.resources);
}
Iterator<ResourceContainer> containers = this.resources.iterator();
int removed = 0;
while (removed < toBeRemoved) {
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.canStore(ResourceType.FUEL)) {
FuelContainer fuelContainer = (FuelContainer) resourceContainer;
if (fuelContainer.getFuelGrade() == grade) {
removed += 1;
}
}
}
}
}
public int getTotalAmountByType(FuelGrade type) {
int totalFuel = 0;
Iterator<ResourceContainer> fuelContainers = this.resources.iterator();
while (fuelContainers.hasNext()) {
FuelContainer fuelContainer = (FuelContainer) fuelContainers.next();
if (fuelContainer.getFuelGrade() == type) {
totalFuel += fuelContainer.getAmount();
}
} return totalFuel;
}
public List<ResourceContainer> getResourceByType(FuelGrade grade) {
List<ResourceContainer> specifiedFuelGrade = new ArrayList<ResourceContainer>();
for (int i = 0; i < this.resources.size(); i++) {
if (this.resources.get(i).canStore(ResourceType.FUEL)) {
FuelContainer fuelContainer = (FuelContainer) this.resources.get(i);
if (fuelContainer.getFuelGrade() == grade) {
specifiedFuelGrade.add(this.resources.get(i));
}
}
} return (ArrayList) specifiedFuelGrade;
}
public class CargoHold extends Room{
private int maximumCapacity;
private List<ResourceContainer> resources;
public CargoHold(RoomTier tier) {
super(tier);
this.maximumCapacity = maximumCapacityFinder(tier);
this.resources = new ArrayList<ResourceContainer>();
}
all the relevant pieces i think
would massively massively appreciate any help
get the iterator and compare the type of each element
if item of the type you need to remove - so remove
i thought i was doing it fine
but i guess now
should it be iterator.remove() to remove it from the original list?
yes
btw if i can get this version to work, then i can get the other too
this isnt working i think
what you mean "from original list"?
the list, of which was created new list? then no of course
i originally have a list of containers
how do i remove from the original list?
iterate the original list
oh yea i did
this.resources.iterator
sorry ive tried everything i can think of, and am feeling pretty drained
i feel like it rly should be working
like
when i dont have containers.remove() it gives me the initial total resources for the specified typ
and when i put containers.remove() the total ends up at 0
idk why its like this
i can send the whole javafile if thats eaasier?
if (fuelContainer.getFuelGrade() == grade) {
removed += 1;
}
```you don't remove in here anything
you forgot to call iterator.remove()
oh i was testing
when i add it back it goes to 0
i used to have
in the other consume class it has iterator.remove()
post a relevant code that doesn't work
ok 1 se
public void consumeResource(ResourceType type, int amount)
throws InsufficientResourcesException {
if (type != ResourceType.REPAIR_KIT) {
throw new IllegalArgumentException();
}
int totalResource = getTotalAmountByType(type);
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> resourceContainers = getResourceByType(type).iterator();
int consumed = 0;
int toBeRemoved = 0;
while (consumed < amount) {
ResourceContainer resourceContainer = resourceContainers.next();
consumed += resourceContainer.getAmount();
toBeRemoved += 1;
}
Iterator<ResourceContainer> containers = this.resources.iterator();
int removed = 0;
while (removed < toBeRemoved) {
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
containers.remove();
removed += 1;
}
}
}
}
and the problem is that after calling this method, the this.resources list still has same items?
it looks like you select whole list in here java while (consumed < amount) { ResourceContainer resourceContainer = resourceContainers.next(); consumed += resourceContainer.getAmount(); toBeRemoved += 1; }
toBeRemoved equals to the size of fuel elements
I bet they expect more smart deleting
imagine, you have fuel elements in list, that represent amount of fuel in it, like : 1, 2, 3, 10
and they ask you to consume 10 of fuel
you iterate through the list, and since the sum of the elements is < 10 till you count whole of them, you mark whole elements into toBeRemoved
even though you need to delete only one last element with value 10
and 3 items will be left in list
is this expected 5 but was 0 about amount of fuel, not about number of elements is the list?
if that's about container, then, I guess, you need to implement removing as I suggested. But if that's amount of fuel, then just drain containers one by one (and remove if it's empty) till you consume needed amount
you code doesn't do neither smart deleting (because you delete all the containers in the row), nor "draining" way, because you work with toBeRemoved in the loop where you actually remove elements from original list
public void consumeResource(ResourceType type, int amount)
throws InsufficientResourcesException {
if (type != ResourceType.REPAIR_KIT) {
throw new IllegalArgumentException();
}
int totalResource = getTotalAmountByType(type);
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
ArrayList<ResourceContainer> updatedList = new ArrayList<ResourceContainer>();
Iterator<ResourceContainer> containers = this.resources.iterator();
int consumed = 0;
while (containers.hasNext()) {
ResourceContainer resourceContainer = containers.next();
if (consumed < amount) {
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
consumed += resourceContainer.getAmount();
containers.remove();
}
}
updatedList.add(resourceContainer);
} this.resources = updatedList;
}
}
@hardy fossil this is now just showing the original values
but i feel like this is as u said?
- don't do like this:
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
```If the exception will be thrown, `else` won't be executed anyways. Use it like this:
```java
if (amount > totalResource)
throw new InsufficientResourcesException();
int totalResource = getTotalAmountByType(type);
...
- in the end you assign o original list the list of removed elements... why?
updatedList.add(resourceContainer);
} this.resources = updatedList;
i thought because i use removed
- this: ```java
while (containers.hasNext()) {
ResourceContainer resourceContainer = containers.next();
if (consumed < amount) {
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
consumed += resourceContainer.getAmount();
containers.remove();
}
}
updatedList.add(resourceContainer);
}
it only adds the elements not removed
you need to run it while consumed not enough and you need more, AND has more elements
besides, your code can consume more then needed
in here ```
consumed += resourceContainer.getAmount();
containers.remove();
imagine you need to remove only 5, but container has 10. But you consume all 10 and remove container
you put updatedList.add(resourceContainer); outside of if
so even though you remove the item from original list
it will be in list, because you still add them to temporary list, which will be assigned to original
you don't need to use additional list at all
you remove using iterator the needed elements
if (consumed < amount) {
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
if ((amount - consumed) < resourceContainer.getAmount()) {
int full = resourceContainer.getAmount();
resourceContainer.setAmount(full - (amount - consumed));
updatedList.add(resourceContainer);
}
consumed += resourceContainer.getAmount();
containers.remove();
}
}
to fix 3)
also, i think we arent supposed to run the function if error is thrown
they want us to end
forget about updatedList
i passed all the error tests
public void consumeResource(ResourceType type, int amount)
throws InsufficientResourcesException {
if (type != ResourceType.REPAIR_KIT) {
throw new IllegalArgumentException();
}
int totalResource = getTotalAmountByType(type);
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> containers = this.resources.iterator();
int consumed = 0;
while (containers.hasNext()) {
ResourceContainer resourceContainer = containers.next();
if (consumed < amount) {
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
if ((amount - consumed) < resourceContainer.getAmount()) {
int full = resourceContainer.getAmount();
resourceContainer.setAmount(full - (amount - consumed));
}
consumed += resourceContainer.getAmount();
containers.remove();
}
}
}
}
}
ok its testing
fingers crossed
same thing
@hardy fossil
if (consumed < amount) { this condition has to be in while loop
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) { why repair_KIT?
aren't you supposed to work only with the type that was passed as argument?
if ((amount - consumed) < resourceContainer.getAmount()) {
int full = resourceContainer.getAmount();
resourceContainer.setAmount(full - (amount - consumed));
}
consumed += resourceContainer.getAmount();
containers.remove();
you anyways keep to delete container
even if it wasn't drained
public void consumeResource(FuelGrade grade, int amount)
throws InsufficientResourcesException {
int totalFuel = getTotalAmountByType(grade);
if (amount > totalFuel) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> containers = this.resources.iterator();
int consumed = 0;
while (containers.hasNext()) {
ArrayList<ResourceContainer> updatedList = new ArrayList<ResourceContainer>();
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.getType() != ResourceType.REPAIR_KIT) {
FuelContainer fuelContainer = (FuelContainer) resourceContainer;
if (fuelContainer.getFuelGrade() == grade) {
if ((amount - consumed) < fuelContainer.getAmount()) {
int full = fuelContainer.getAmount();
fuelContainer.setAmount(full - (amount - consumed));
updatedList.add(fuelContainer);
}
if (consumed < amount) {
consumed += fuelContainer.getAmount();
} else {
updatedList.add(resourceContainer);
}
} else {
updatedList.add(fuelContainer);
}
} else {
updatedList.add(resourceContainer);
} this.resources = updatedList;
}
}
}
@hardy fossil
it wasnt working using remove
so im trying it like this
just making a list and not adding any that are removed
adding everything else
it has worked for 3 tests
only 1 test not working now
@hazy moat
you're defining and updating the list in the loop itself
that obviously wont work
do you know about list.removeIf()?
removes all elements matching the predicate you give it
eg strings.removeIf(str -> str.equals("abc")) removes all elements from strings that equal "abc"
wait what do you actually want to do
how do you want to remove the elements from the list
specifically
this is the test thats failing
public void consumeResource(FuelGrade grade, int amount)
throws InsufficientResourcesException {
int totalFuel = getTotalAmountByType(grade);
if (amount > totalFuel) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> containers = this.resources.iterator();
int consumed = 0;
while (containers.hasNext()) {
ArrayList<ResourceContainer> updatedList = new ArrayList<ResourceContainer>();
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.canStore(ResourceType.FUEL)) {
FuelContainer fuelContainer = (FuelContainer) resourceContainer;
if (fuelContainer.getFuelGrade() == grade) {
if ((amount - consumed) < fuelContainer.getAmount()) {
int full = fuelContainer.getAmount();
fuelContainer.setAmount(full - (amount - consumed));
updatedList.add(fuelContainer);
} else if (consumed < amount) {
consumed += fuelContainer.getAmount();
} else {
updatedList.add(resourceContainer);
}
} else {
updatedList.add(fuelContainer);
}
} else {
updatedList.add(resourceContainer);
} this.resources = updatedList;
}
}
}
^^^not working
public void consumeResource(ResourceType type, int amount)
throws InsufficientResourcesException {
if (type != ResourceType.REPAIR_KIT) {
throw new IllegalArgumentException();
}
int totalResource = getTotalAmountByType(type);
if (amount > totalResource) {
throw new InsufficientResourcesException();
} else {
Iterator<ResourceContainer> containers = this.resources.iterator();
int consumed = 0;
while (containers.hasNext()) {
ArrayList<ResourceContainer> updatedList = new ArrayList<ResourceContainer>();
ResourceContainer resourceContainer = containers.next();
if (resourceContainer.getType() == ResourceType.REPAIR_KIT) {
if ((amount - consumed) < resourceContainer.getAmount()) {
int full = resourceContainer.getAmount();
resourceContainer.setAmount(full - (amount - consumed));
updatedList.add(resourceContainer);
}
if (consumed < amount) {
consumed += resourceContainer.getAmount();
} else {
updatedList.add(resourceContainer);
}
} else {
updatedList.add(resourceContainer);
} this.resources = updatedList;
}
}
}
^^^similar function that works, just a different resource type
@onyx trout any ideas whats going on?
First thing I would do is move some of that logic into another method because consumeResource is far too complex to work with.
I'd probably also create a "consume" method in the ResourceContainer class, which accepts an amount to attempt to consume and returns the amount it was able to consume.
You could then simply do consumed += container.consume(amount - consumed) in your loop, which would cut that down quite a bit.
consumed += resourceContainer.getAmount();```
Maybe I'm mis-reading this, but why are you setting the consumed amount = to the amount remaining in the resource container?
I expect that's producing your strange results.
Also:
```} this.resources = updatedList;```
This statement should not be written on the same line as the closing brace.