#java #oop #arraylist
Вопрос:
Мне было интересно, есть ли способ или библиотека, которую я могу использовать для выполнения следующих действий:
У меня есть список объектов, в котором у каждого объекта есть имя.
Список всегда должен быть уникальным и содержать не более 5 элементов, таких как [E1,E2,E3]
Если, например, список имеет начальную форму [E3,E5]
, и я добавляю объект, его имя должно быть E1, и список будет [E1,E3,E5]
или [E3,E5,E1]
это не имеет значения, если имя уникально и элемент добавляется в список, начиная с 1 до 5.
Если добавить еще один элемент, он должен быть [E3,E5,E1,E2]
, всегда с уникальным именем и между 1 и 5
Это мои неудачные попытки,
StartNode node = new StartNode(); node.setName("E1"); for (int i = 0; i lt; circuit.getNbStartNodes(); i ) { for (int j = 1; j lt;= circuit.getNbStartNodes(); j ) { String test = ((StartNode) circuit.getStartNode(j)).getName(); if (("E" j).equalsIgnoreCase(test) amp;amp; ("E" j).equalsIgnoreCase(node.getName()) ) { break; } else node.setName("E" j); } } /*while (t lt;= circuit.getNbStartNodes()) { for (int j = 0; j lt; circuit.getNbStartNodes(); j ) { String test = ((StartNode) circuit.getStartNode(j)).getName(); if (("E" t).equalsIgnoreCase(test) || ("E" t).equalsIgnoreCase(node.getName())) break; else { node.setName("E" t); } } t ; } */ /* for (int i = 1; i lt;= circuit.getNbStartNodes(); i ) { for (int j = 0; j lt; circuit.getNbStartNodes(); j ) { String test = ((StartNode) circuit.getStartNode(j)).getName(); if (!("E" i).equalsIgnoreCase(test)) { node.setName("E" i); t=0; break; } } if (t==0) break; else continue; */ //String test = ((StartNode) circuit.getStartNode(i)).getName(); //for (int j = 1; j lt;= circuit.getNbStartNodes(); j ) { // if (!("E" j).equalsIgnoreCase(test)) // node.setName("E" j); //}
Что я сделал не так в своем коде?
Комментарии:
1. Мне было интересно, содержит ли ваш первоначальный список
E3
иE5
имеет ли значение , какой элемент будет добавлен? Должно ли это бытьE1
, или что-то изE1
этого ,E2
илиE4
нормально?
Ответ №1:
- Создайте небольшой логический массив, чтобы отслеживать, какие имена уже используются, и соответствующим образом заполните его
- Найдите первый неиспользуемый элемент и используйте его в качестве идентификатора.
boolean[] used = new boolean[circuit.getNbStartNodes()]; for (int i = 0; i lt; used.length; i ) { int index = Integer.parseInt(((StartNode) circuit.getStartNode(j)).getName().substring(1)) - 1; // should be in range 0..4 used[index] = true; } String name = "E"; for (int i = 0; i lt; used.length; i ) { if (!used[i]) { name = String.valueOf(i 1); // starting from 1 break; } } System.out.println("free name: " name); StartNode node = new StartNode(); node.setName(name); // add new node to circuit, etc.
Комментарии:
1. если, например, все используемые значения являются истинными, второй цикл не выполняется, как вы думаете, могу ли я инициировать массив логических значений, содержащий мои уже существующие узлы, которые превратятся в true, а остальные будут оставлены как ложные, таким образом, будет выполнен второй цикл ? также я думаю, что он отсутствует
for (int j = 0; j lt; circuit.getNbStartNodes(); j ) {
для первого цикла2. Идея
used
состоит в том, чтобы отслеживать, какие узлы используются, по умолчанию используются все элементы этого массиваfalse
. Если после первого цикла не останется свободного места, второй цикл все равно запустится. Размерused
совпадает сcircuit.getNbStartNodes()
, поэтому не имеет значения, какое значение следует использовать в первом цикле (нет необходимости вызывать метод, если есть равныйused.length
).
Ответ №2:
При небольших значениях решение Алекса работает нормально.
Однако, если вы когда-нибудь столкнетесь с вариантом использования, когда количество элементов станет потенциально большим, вы можете использовать a TreeSet
для отслеживания неиспользуемых чисел. Кроме того, nextCeilValue
это следующий номер, который нужно выбрать, когда нет удаленных номеров.
В приведенном ниже коде я создал UniqueNumber
класс, который способен к get
следующему номеру или remove
заданному номеру. Обратите внимание, что этот код содержит целые числа, начинающиеся с 0. Конечно, вы можете легко преобразовать это в свои электронные номера, используя функцию i -gt; "E" (i 1)
.
public class UniqueNumber { private int nextCeilValue; private final TreeSetlt;Integergt; removedNumbers = new TreeSetlt;gt;(Integer::compare); public int get() { if (removedNumbers.isEmpty()) { return nextCeilValue ; } else { int number = removedNumbers.first(); removedNumbers.remove(number); return number; } } public boolean remove(int number) { if (number lt; 0 || number gt; nextCeilValue) { return false; } if (number == nextCeilValue) { nextCeilValue--; } else { removedNumbers.add(number); } return true; } public int size() { return nextCeilValue - removedNumbers.size(); } }
Чтобы проверить это, нам сначала нужно смоделировать вашу начальную ситуацию. В нашем мире целых чисел, начинающемся с нуля, нам нужны числа 2 и 4 (представляющие E3 и E5). В приведенном ниже коде нам нужно вызвать get
пять раз, а затем удалить элементы 0, 1 и 3. Конечно, мы могли бы создать UniqueNumber(int... initialValues)
конструктор, который делает это под капотом.
UniqueNumber un = new UniqueNumber(); for (int i = 0; i lt; 5; i ) { un.get(); } un.remove(0); // Remove E1 un.remove(1); // Remove E2 un.remove(3); // Remove E4
Чтобы получить следующее значение, просто используйте это:
StartNode node = new StartNode(); node.setName("E" (un.get() 1));
Комментарии:
1. спасибо, сэр, я использую этот для своих ворот, так как у меня будет максимум 50 ворот.