Я просмотрел другие вопросы, но не могу найти ответ, который ищу.
Мне трудно понять, как создать цикл, который добавляет объект класса в ArrayList
, только если его имя еще не используется в списке.
Это мой класс.
package myPackage;
public class Cube {
private int length;
private String name;
public Cube(int initLength, String initName) {
this.length = initLength;
this.name = initName;
}
Я хотел бы создать новые кубы и добавить их в список. Вот код, с которым я пытаюсь это сделать.
В цикле while я не могу понять, как определить, использовалось ли имя или нет
package myPackage;
import java.util.ArrayList;
import java.util.Scanner;
public class PartFive {
public static void main(String[] args) {
ArrayList<Cube> cubelist = new ArrayList<>();
Cube oshea = new Cube (13, "oshea");
Cube mike = new Cube (7, "tony");
cubelist.add(oshea);
cubelist.add(mike);
Scanner reader = new Scanner(System.in);
while (true) {
System.out.println("enter cube name (blank quits): ");
String name = reader.nextLine();
if (name.equals("")){
break;
}
System.out.println("enter side length: ");
int length = Integer.valueOf(reader.nextLine());
Cube newcube = new Cube(length, name);
if (cubelist.contains(newcube.name)) {
// dont add to list
}
else {
cubelist.add(newcube);
}
}
reader.close();
System.out.println(cubelist);
}
}
Любая конструктивная критика и предложения приветствуются.
Заменять
if (cubelist.contains(newcube.name)) {
dont add to list
}
else {
cubelist.add(newcube);
}
с
boolean found = false;
for(Cube cube: cubelist){
if (cube.getName().equals(name)) {
found = true;
break;
}
}
if (!found) {
cubelist.add(newcube);
}
Идея состоит в том, чтобы использовать переменную boolean
, чтобы отслеживать, существует ли уже в списке куб с тем же именем, что и у входных данных name
. Для этого выполните итерацию cubelist
и, если найден куб с таким же именем, как у входа name
, измените состояние переменной boolean
и break
цикла. Если состояние переменной boolean
не меняется на протяжении всего цикла, добавьте куб в список.
Из кода в вашем вопросе:
if (cubelist.contains(newcube.name)) {
// don't add to list
}
else {
cubelist.add(newcube);
}
Метод содержит в классе java.utilArrayList
— это правильный путь, но вы должны знать, что метод contains
[в конечном итоге] вызывает метод , равный своего типа элемента. В вашем случае тип элемента Cube
. Поэтому вам нужно добавить метод equals
в класс Cube
. Я не знаю, что определяет, равны ли два объекта Cube
, но я предполагаю, согласно вашему вопросу, что они равны, если у них одинаковые name
, даже если у них разные length
. Далее я предполагаю, что name
не может быть нулевым. Основываясь на этих предположениях, вот метод equals
. Вы должны добавить этот метод в класс Cube
.
public boolean equals(Object obj) {
boolean areEqual = false;
if (this == obj) {
areEqual = true;
}
else {
if (obj instanceof Cube) {
Cube other = (Cube) obj;
areEqual = name.equals(other.name);
}
}
return areEqual;
}
Теперь в методе main
класса PartFive
вы можете использовать следующий if
, чтобы добавить Cube
в список.
if (!cubelist.contains(newcube)) {
cubelist.add(newcube);
}
Вы можете проверить наличие повторяющихся имен в массиве кубелистов, используя лямбда-выражения (для лучшей читабельности):
boolean isNameAlreadyExisting = cubelist.stream()
.anyMatch(cube -> cube.getName().equals(newcube.getName())); // this is returning true if any of the cubelist element's name is equal with the newcube's name, meaning that the name is already existing in the cubelist
if (!isNameAlreadyExisting) {
cubelist.add(newcube);
}
Одна вещь, которую вы должны сделать, это удалить инструкцию while(true), которая вызывает бесконечный цикл. Другое предложение состоит в том, чтобы отображать имена объектов, содержащихся в кубе, чтобы убедиться, что имена действительно не дублируются:
cubelist.stream()
.map(Cube::getName)
.forEach(System.out::println);