Вы хотите, чтобы более низкая частота повышалась так:
public int compare(TreeNodeHuffman p1, TreeNodeHuffman p2) {
if (p1.frequency < p2.frequency) return 1;
if (p1.frequency > p2.frequency) return -1;
return 0;
}
}
Если вы хотите протестировать ее, отправьте ее в один пул с потоком и посмотрите порядок обрабатываемых заданий вместо строки или итератора , как говорит doc в http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#iterator%28%29 :
Возвращает итератор по элементам в этой очереди. Итератор не возвращает элементы в каком-либо конкретном порядке.
Можно увидеть http://docs.oracle.com/javase/7/docs/api/java/util/ concurrent / Executors.html # newSingleThreadExecutor% 28% 29 для быстрого однопоточного пула, чтобы проверить это.
Один интересный необычный случай использования, который я нашел, я описал здесь здесь . Короче говоря, предотвращая наследование от вашего класса типа int, вы покупаете себе возможность заменить его встроенным типом в будущих версиях вашей библиотеки, не рискуя нарушить код пользователя.
Но более распространенным примером является девиртуализация . Если вы отметите свой класс как final, компилятор может применить определенные оптимизации во время выполнения. Например,
struct Object {
virtual void run() = 0;
virtual ~Object() {}
};
struct Impl final : Object
{
void run() override {}
};
void fun(Impl & i)
{
i.run(); // inlined!
}
Вызов i.run()
может быть теперь встроен из-за спецификатора final
. Компилятор знает, что vtable look-up не понадобится.
final
может быть полезна, когда вы предоставляете (вид) фасад первоначальному интерфейсу, который проще использовать подклассами. Рассмотрим:
class IMovable {
public:
void GoTo(unsigned position) = 0;
}
class Stepper : public IMovable {
public:
void GoTo(unsigned position) final;
protected:
virtual void MoveLeft() = 0;
virtual void MoveRight() = 0;
}
void Stepper::GoTo(unsigned position) {
for(;current_pos < position; current_pos++) {
MoveRight();
}
for(;current_pos > position; current_pos--) {
MoveLeft();
}
}
Теперь, если вы хотите получить Stepper, вы увидите, что вы должны переопределить MoveRight
и MoveLeft
, но вы не должны переопределять GoTo
.
Это очевидно на этом маленьком примере, но если IMovable
имеет 20 методов, а у Stepper 25, и были реализации по умолчанию, чем вам может быть трудно выяснить, что вы должны и что вы должны " t переопределить. Я встречал такую ситуацию в библиотеке, связанной с оборудованием. Но я бы не назвал это серьезной проблемой, заслуживающей внимания стандартом;)
final
; Я уже знал, почему они существуют, даже перед тем, как задать вопрос ^^ & quot;
– Morwenn
10 December 2013 в 15:36