Увеличивайте счетчик каждый раз, когда добавляется новая дорожка, и всегда выбирайте наименьшее значение (> = 1), которое еще не назначено - PullRequest
0 голосов
/ 13 февраля 2020

В настоящее время я работаю над проектом симуляции поезда, и у меня есть список, в котором я сохраняю все треки:

    private List<Track> tracks;

    public void addTrack(Track track) {
        this.tracks.add(track);
    }

    public void removeTrack(Track track) {
        if (!tracks.contains(track)) {
            this.tracks.remove(track);
        } else {
            Terminal.printError("track with id " + track.getId() + " doesn't exist.");
        }
    }

Я хочу назначить каждому треку идентификатор при его добавлении (начиная с 1 ). Кроме того, всегда выбирается следующий бесплатный идентификатор. Например, если назначены идентификаторы 1,3,4,5, используется следующий идентификатор 2.

E. g.:

Добавить трек ... -> ID: 1

Добавить трек ... -> ID: 2

Удалить трек 1

Добавить трек ... -> ID: 1

Я бы использовал карту и каждый раз, когда добавлял новый трек, увеличивал счетчик на единицу. Однако, если я удалю ID и добавлю новую дорожку, будут "пробелы".

Какой хороший способ сделать это?

Ответы [ 2 ]

3 голосов
/ 13 февраля 2020

Одним из способов будет отслеживание каждого назначенного идентификатора в другой структуре данных, возможно, BitSet, в частности, BitSet # nextClearBit (int) метод

Так что каждый раз, когда вы помещаете что-то в List<Tracks> вы устанавливаете относительный индекс в BitSet и удаляете, когда удаляется Track.

Что-то вроде следующего

BitSet b = new BitSet();
// set the bits while adding tracks
b.set(0);
b.set(1);
b.set(2);

b.clear(1); // some track gets removed, so unset the bit
System.out.println(b); // {0, 2}

System.out.println(b.nextClearBit(0)); // 1
0 голосов
/ 13 февраля 2020

Как и Саиф Асиф, упомянутый в его ответе, вы можете использовать другую структуру данных для отслеживания идентификаторов.

BitSet - это один из способов go, другой - отслеживание назначенных вами идентификаторов и отозвано с помощью TreeSet, который будет поддерживать идентификаторы для вас

, например,

public class IdTracker {

    private TreeSet<Long> available;
    private TreeSet<Long> current;

    public IdTracker() {
        this.available = new TreeSet<Long>();
        this.current = new TreeSet<Long>();
    }

    public long getNextId() {
        //Check to see if this is the first time being called, setting initial id to 1
        if (available.isEmpty() && current.isEmpty()) {
            current.add(1L);
            return 1L;
        }

        //Check to see if we have any available values to use
        if (!available.isEmpty()) {
            //Remove from available and assign to current
            Long availableId = available.first();
            available.remove(availableId);
            current.add(availableId);
            return availableId;
        }

        //There are no available id's, get the highest current id and increment
        Long highestCurrentId = current.last();
        Long nextId = highestCurrentId + 1;
        current.add(nextId);
        return nextId;
    }

    public void removeId(long id) {
        //Remove from the current (if there) and place into available
        if (current.remove(id)) {
            available.add(id);
        } else {
            //Handle your failure case
        }
    }
}

Так что в вашем примере вы должны сделать

private List<Track> tracks;
private IdTracker idTracker;

public void addTrack(Track track) {
    long id = idTracker.getNextId();
    track.setId(id);
    this.tracks.add(track);
}

public void removeTrack(Track track) {
    if (tracks.contains(track)) {
        this.tracks.remove(track);
        this.idTracker.removeId(track.getId());
    } else {
        Terminal.printError("track with id " + track.getId() + " doesn't exist.");
        }
    }

...