2017-02-03 11 views
0

Я попытался реализовать очередь приоритетов с использованием массива объектов «Элементы очереди», в которых есть некоторые данные (строка) и целое число, которое является приоритетом. Я пытаюсь сопоставить эти элементы таким образом, чтобы при добавлении нового объекта в очередь я мог выполнять итерацию по элементам и добавлять новый элемент в нужное место и перемещать все элементы, которые теперь находятся за ним назад, однако, когда я добавляю новый элемент в очередь. Я получаю исключение с нулевым указателем. Я включу весь свой код, но метод toString был просто скопирован из очереди, поэтому он не будет работать должным образом.Сравнение атрибута объекта в реализации очереди приоритетов

class QueueItem implements Comparable<QueueItem> { 
    String data; 
    int pri; 

    public QueueItem(String data, int pri) { 
     this.data = data; 
     this.pri = pri; 
    } 

    @Override 
    public int compareTo(QueueItem item) { 
     return this.data.compareTo(item.data); 
    } 
} 

public class PriorityQueue implements Queue<String> { 
    private QueueItem[] arr; 
    private int frontPos, backPos; 

    public PriorityQueue() { 
     arr = new QueueItem[20]; 
     backPos = -1; 
     frontPos = 0; 
    } 

    public boolean isEmpty() { 
     return frontPos == (backPos + 1) % arr.length; 
    } 

    public String front() { 
     if (frontPos == (backPos + 1) % arr.length) 
      throw new QueueException("Empty Queue - front"); 
     return arr[frontPos].data; 
    } 

    public int frontPri() { 
     if (frontPos == (backPos + 1) % arr.length) 
      throw new QueueException("Empty Queue - frontPri"); 
     return arr[frontPos].pri; 
    } 

    public void addToPQ(String str, int x) { 
     if (arr.length==0) { 
      arr[frontPos] = new QueueItem(str, x); 
      frontPos++; 
      return; 
     } 
     else { 
      for (int i = 0; i < arr.length; i++) { 
       arr[i].compareTo(new QueueItem(str, x)); 
      } 
     } 
    } 

    public void deleteFront() { 
     if (frontPos==(backPos+1)%arr.length) { 
      throw new QueueException("Empty Queue - deleteFront"); 
     } 
     frontPos = (frontPos+1)%arr.length; 
    } 

    public String toString() { 
     if (frontPos == (backPos + 1) % arr.length) { 
      return "<>"; 
     } 
     StringBuffer sb = new StringBuffer(); 

     sb.append('<'); 

     int pos = frontPos; 
     while (pos != backPos) { 
      sb.append(arr[pos]); 
      sb.append(','); 
      pos = (pos + 1) % arr.length; 
     } 

     sb.append(arr[backPos]); 
     sb.append('>'); 

     return (sb.toString()); 
    } 
} 

public interface Queue<String> { 
    public void addToPQ(String str, int x); 

    public void deleteFront(); 

    public String front(); 

    public boolean isEmpty(); 

    public int frontPri(); 
} 

class QueueException extends RuntimeException { 
    QueueException(String s) { 
     super("Tried to apply " + s + " to empty queue"); 
    } 
} 

public class pqTest { 
    public static void main(String[] args) { 
     PriorityQueue pQ = new PriorityQueue(); 
     if (pQ.isEmpty()) { 
      System.out.println("Queue is Empty - isEmpty"); 
     } 
     pQ.addToPQ("Dog", 4); 
     pQ.addToPQ("Cat", 20); 
     pQ.deleteFront(); 
     pQ.addToPQ("Fish", 2); 
    } 
} 
+0

Возможного дубликата [Что такое NullPointerException, и как это исправить?] (http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – nhouser9

+0

Почему бы не использовать java.util.priorityqueue ? – user152468

+0

Вы используете 'arr.length == 0', чтобы определить, пуста ли ваша очередь. Однако ваша очередь инициализируется размером 20. Используйте отладчик, чтобы найти исключение nullpointer. – user152468

ответ

0

Вы получаете NullPointerException, потому что, когда вы добавляете второй пункт, вы идете к другому даного где итераций по массиву с одним ненулевым элементом и 19 нулей. Поэтому вам нужно изменить свой код, чтобы проверить, имеет ли элемент массива значение i, и если это так, назначьте ему новый элемент.

+0

нет, это уже при добавлении первого элемента. Просто отладил его. – user152468

1

Проблема заключается в том, что arr - это размер 20, поэтому первый элемент даже не будет добавлен через оператор if в вашем методе addToPQ, потому что arr.length != 0. Поэтому он перейдет к вашему заявлению else, которое выполняет итерацию через каждый элемент в arr. Но arr имеет 20 нулевых элементов, так как каждое пятно внутри массива QueueItems не было инициализировано. Таким образом, вы должны изменить свое состояние в заявлении, если frontPos == 0 и изменить условие завершения в цикле, чтобы i < frontPos так что метод не будет перебирать нулевые элементы в arr

public void addToPQ(String str, int x) { 
     if (frontPos==0) { 
      arr[frontPos] = new QueueItem(str, x); 
      frontPos++; 
      return; 
     } 
     else { 
      QueueItem item = new QueueItem(str, x); 
      for (int i = 0; i < frontPos; i++) { 
       arr[i].compareTo(item); 
      } 
     } 
    } 
+0

Это теперь работает для обработки первого элемента, теперь, когда я добавляю второй элемент в очередь, я получаю OutOfMemoryError, и он говорит, что не может найти локальную переменную 'str'? – Chaz

+0

@Chaz проверить мои изменения. Я считаю, что это было потому, что у вас был 'arr [i] .compareTo (новый QueueItem (str, x))', который действительно неэффективен, потому что вы ненужно создаете один и тот же объект несколько раз. Таким образом, я сделал новый элемент за пределами цикла, так что цикл может работать эффективно по сравнению с новым элементом. –