#java #arraylist
#java #arraylist
Вопрос:
У меня есть ArrayList, который заполняется случайным числом GameObj
экземпляров при каждом запуске программы.
Если объект вступает в контакт с другим объектом в ArrayList, он установит логическое значение, вызываемое visible
из true
to false
.
Есть ли способ проверить, все ли экземпляры элементов в ArrayList были установлены в false
through:
XXXX.visible = false
Как только я смогу проверить, все ли они установлены false
.
Комментарии:
1.
list.stream().allMatch
2.
bool allBricks = true; for(GameObj brick : yourList) { if(brick.visible) { allBricks = false; break; } } if(allBricks) { System.out.println("Well Done, Game over."); }
3. В таких сценариях, как этот, другой подход заключается в том, чтобы иметь счетчик, например
int bricksHits
, который увеличивается при попадании кирпича. Затем вы можете использовать простой оператор if, такой какif(bricksHit >= totalBricks) { ... }
, который проверяется только один раз, а не перебирать весь список (в худшем случае).4. Да, давайте предложим решение для функционального программирования новичку в
Boolean
andArrayList
.
Ответ №1:
Вы можете использовать Stream.noneMatch()
для этого:
if (bricks.stream().noneMatch(GameObj::isVisible)) {
doStuffIfAllBricksAreInvisible();
}
Это возвращает true, если все блоки невидимы.
Кроме того, я бы рекомендовал взглянуть на Stream.allMatch()
, который возвращает true, если все элементы списка соответствуют заданному предикату.
Использование allMatch()
этого будет выглядеть следующим образом:
if (bricks.stream().allMatch(b -> !b.isVisible())) {
doStuffIfAllBricksAreInvisible();
}
Чтобы завершить это, вы также можете взглянуть на Stream.anyMatch()
, который возвращает true, если один из элементов соответствует заданному предикату.
Комментарии:
1. @HBU Вы должны настроить эту часть в соответствии с вашими потребностями в вашем gameObj. Не могли бы вы добавить это к своему вопросу? Я также обновил свой пост.
2. Не используйте общедоступные поля, лучше создайте для него средство получения. В качестве альтернативы вы можете использовать
b -> b.visible
вместо ссылки на метод.3. Это догматическая Java, но это не имеет смысла. Если у вас есть что-то, что должно быть общедоступным, удалите шаблонный код и сделайте его общедоступным. Аргумент о том, что абстракция имеет смысл, поскольку вы можете изменить реализацию
getIsVisible
, на самом деле никогда не выполняется. Единственное место, где я бы использовал этот шаблонный код, — это при взаимодействии с библиотекой, поведение которой работает с помощью таких методов, как Hibernate. Худшими являются POJOs, воплощение запоминания решения и неправильного его применения вместо написания чистого кода.
Ответ №2:
Если вы используете Java <8, одним из способов будет сохранить размер arraylist при инициализации в переменной (скажем, имя переменной — count ).
При изменении флага с true на false уменьшите количество на 1. Если значение flag уже равно false, ничего не делайте. Теперь вы можете просто проверить, равно ли количество 0 или нет.
Если количество равно 0, выведите «Молодец, игра окончена» или продолжайте игру.
Для Java 8 или выше вы можете использовать streams API, как предложено в других ответах.
Комментарии:
1. Просто будьте осторожны с подобным решением, поскольку каждый экземпляр изменяет одну и ту же переменную, и, скорее всего, потребуется потокобезопасное решение.
Ответ №3:
Я предлагаю использовать anyMatch, потому что метод allMatch возвращает true, когда список пуст
if (!bricks.stream().anyMatch(GameObj::isVisible)) {
// TODO when visible balls not found (all are invisible)
}
Комментарии:
1. Хотя вы правильно подметили, все будет зависеть от его варианта использования, потребностей в скорости и дизайна. Например, он может захотеть
List
, чтобы возвращалось значение emptytrue
илиfalse
, или может быть гарантировано, что оно никогда не будет пустым. Что касается скорости, которая часто играет важную роль в игровом дизайне, простой цикл for с abreak
намного быстрее, чем функциональное решение. Общеизвестно, что функциональный интерфейс Java намного медленнее, чем перебор альтернатив при работе с небольшимArrayList
.
Ответ №4:
Проверьте List
, все ли boolean
значения true
или хотя бы одно значение равно false
List<Boolean> booleans = new ArrayList<>();
booleans.add(false);
booleans.add(true);
booleans.add(true);
booleans.add(true);
boolean areAllTrue = booleans.stream().allMatch(Boolean::booleanValue);
// equivalent to:
boolean areAllTrue = booleans.stream().allMatch(b -> b);
Важное примечание: If booleans.size()
равно нулю; результат allMatch()
всегда true
. Итак, вы должны сначала проверить размер или в зависимости от ваших потребностей контекста.
Ответ №5:
Если вы новичок в Java, вы, вероятно, захотите использовать цикл for, подобный этому:
bool allFalse = true;
for(int index = 0; index < arrayList.size(); index)
if(arrayList[index].visible) {
allFalse = false;
break;
}
break;
завершает цикл for, как только вы найдете первое истинное значение, поскольку вам больше не нужно проверять.
Это сработает, если вы знаете arrayList
, что оно не пустое, но может иметь смысл иметь allFalse
значение false для пустого List
, поскольку то, чего там нет, не является ни true, ни false .
Для проверки чего-либо в an ArrayList
с небольшим количеством элементов цикл for с a break
также будет значительно быстрее, чем a Stream
. Хотя это может и не иметь значения в целом, где читаемость и удобство обслуживания имеют первостепенное значение, в играх это часто имеет значение, особенно если он часто выполняет эту проверку. Однако это зависит от его варианта использования. Скорость может быть не важна.