#java #arrays #arraylist
#java #массивы #arraylist
Вопрос:
У меня есть два разных ArrayList
экземпляра, один из type Container
и один из type String
. Первый — это список «запрещенных товаров» (строк) для страны, а другой — список контейнеров на судне. Корабль путешествует по стране, и в контейнерах производится поиск запрещенных товаров. Если в контейнере contains
запрещенные товары, этот контейнер следует удалить / удалить.
public Customs(String country)
{
countryName = country;
bannedGoods = new ArrayList<String>();
}
public Ship(String n, double weight)
{
emptyWeight = totalWeight = weight;
name = n;
containers = new ArrayList<Container>();
}
У меня уже есть метод в классе Ship, который удаляет контейнер:
public void removeContainer(int i)
{
if(i >= 0 amp;amp; i < containers.size()) {
Container r = containers.remove(i);
totalWeight = totalWeight - r.getWeight();
}
}
Я пытаюсь создать метод для inspect
отправки контейнеров. Я хочу использовать два цикла for для каждого из массивов, но, похоже, я не могу понять это правильно! Может кто-нибудь помочь мне использовать два цикла для поиска в массивах? Кроме того, я думаю, что мне нужно будет использовать итератор ( remove
в частности, функцию) в цикле, но это также сбивает меня с толку. Должен remove
ли метод итератора заменить метод, который я уже написал в class ship? Вот что у меня есть:
public void inspect(Ship ship)
{
for (String good : bannedGoods) {
for (String con : containers) {
if (con.contains(good) {
container.remove();
}
}
}
И вот моя попытка итератора:
for(String good : bannedGoods) {
Iterator<String> it = ship.containers.iterator();
while (it.hasNext())
if (ship.contains(good))
it.remove();
}
Ответ №1:
Я не думаю, что вам нужно 2 цикла for. Вы должны перебирать запрещенные товары и просто удалять их из контейнеров.
Кроме того, предполагая, что containers
список имеет тип string
, как это указано в вашей первой строке : I have two different arrayLists of the same type String
public void inspect(Ship ship, ArrayList<String> bannedGoods){
if (ship == null || bannedGoods == null || bannedGoods.isEmpty())
return;
for(String good : bannedGoods){
ship.containers.remove(good);
}
}
Если, Containers
имеет тип Container
и содержит список контейнеров (Arraylist of string)
, который доступен с помощью метода get_containers()
, будет работать следующее:
public void inspect(Ship ship, ArrayList<String> bannedGoods){
if (ship == null || bannedGoods == null || bannedGoods.isEmpty())
return;
for(String good : bannedGoods){
for(Container container : ship.containers){
container.get_containers().remove(good);
}
}
}
Комментарии:
1.
containers
это списокContainer
объектов, а не строк. Такжеinspect
предположительно является методом экземпляраCustoms
, поэтому он имеет прямой доступ кbannedGoods
списку.2. OP записал это как первую строку :
I have two different arrayLists of the same type String
3. Может показаться, что второй список находится внутри
Container
. См . Конструктор ship,containers = new ArrayList<Container>();
.4. Да, извините! Один массив имеет тип String, а другой — тип Container . Извините за ошибку! Я отредактировал свой пост.
5. @SamStan Это отвечает на ваш вопрос?
Ответ №2:
Вы можете придерживаться тех методов, которые используете в данный момент. Но имейте в виду, что вам нужно либо использовать метод удаления итератора, либо не использовать итераторы. Итак, чтобы использовать ваш метод удаления, либо реализуйте Iterable
, либо просто используйте индексы вместо итераторов:
for (int i = 0; i < bannedGoods.size(); i )
{
for (int j = 0; j < containers.size();) // NOTE: no j here
{
Container c = containers.get(j);
if (c.contains(bannedGoods.get(i))
c.removeContainer(j);
else
j ; // only if you don't remove the container increment
// j - when removing the next element gets current
// index
}
}
Ответ №3:
На самом деле вы довольно близки к этому, и вы проделали хорошую работу, сосредоточив внимание на принципах объектно-ориентированного программирования при разработке своих классов. Я думаю, что сейчас вам нужно сосредоточиться на том, чтобы быть более осторожным с вашими типами. Ниже приведены некоторые предлагаемые изменения в ваших классах ( Container
не показаны, но я предполагаю, что у него есть public boolean contains (String s)
метод, который проверяет, есть ли в контейнере определенный товар s
внутри.
import java.util.*;
public class Ship implements Iterable<Container> {
private double emptyWeight, totalWeight, weight;
private String name;
private List<Container> containers = new ArrayList<Container>();
public Ship(String n, double weight) {
emptyWeight = totalWeight = weight;
name = n;
}
private void removeContainer(int i) {
if (i >= 0 amp;amp; i < containers.size()) {
Container r = containers.remove(i);
totalWeight = totalWeight - r.getWeight();
}
}
public Iterator<Container> iterator() {
return new Iterator<Container> {
private index = 0;
private Container previous = null;
public boolean hasNext() {
return index < containers.size();
}
public Container next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
previous = containers.get(index );
return previous;
}
public void remove() {
if (previous == null) {
throw new IllegalStateException();
}
removeContainer(containers.indexOf(previous));
previous = null;
}
};
}
}
Я предлагаю removeContainer
придерживаться вашего Ship
класса, поскольку он отвечает за отслеживание того, как изменяется его вес при удалении контейнера. По той же причине не разрешайте внешним классам напрямую обращаться к своему containers
списку. Таким образом, вы можете запретить другому коду добавлять или удалять значения из этого списка без weight
правильного обновления. Я бы предложил сделать containers
список закрытым и предоставить Iterator
возможность пользователям класса взаимодействовать с контейнерами.
В вашем Customs
классе вы бы использовали метод Iterator
‘s remove
для удаления Container
экземпляров, вызывающих нарушения:
import java.util.*;
public class Customs {
private String countryName;
private List<String> bannedGoods = new ArrayList<String>();
public Customs(String country) {
countryName = country;
}
public void inspect(Ship ship) {
for (String good : bannedGoods) {
for (Iterator<Container> it = ship.iterator(); it.hasNext();) {
Container container = it.next();
if (container.contains(good) {
it.remove();
}
}
}
}
}