Исключение нулевого указателя во время Stream.forEach

StackOverflow https://stackoverflow.com//questions/25007513

  •  20-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь смоделировать медиану бесконечных номеров. Это мой код

package hard;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.stream.Stream;

public class Median
{
static Queue<Integer> minHeap;

static Queue<Integer> maxHeap;

{
    minHeap = new PriorityQueue<>();

    maxHeap = new PriorityQueue<>();
}

private static void add(Stream<Integer> randomNos)
{

    randomNos.forEach(no ->
    {
        if (minHeap.size() == 0 || no < minHeap.peek())
        {
            minHeap.add(no);
        }
            else
            {
                maxHeap.add(no);
            }

            int diff = minHeap.size() - maxHeap.size();

            if (Math.abs(diff) > 1)
            {
                if (diff < 0)
                {
                    minHeap.add(maxHeap.peek());
                }
                else
                {
                    maxHeap.add(minHeap.peek());
                }
            }
        });

}
private static int median()
{
    int median = 0;

    if ((minHeap.size() + maxHeap.size()) % 2 == 0)
    {
        median = (minHeap.peek() + maxHeap.peek()) / 2;
    }
    else
    {
        if (minHeap.size() < maxHeap.size())
        {
            median = maxHeap.peek();
        }
        else
        {
            median = minHeap.peek();
        }
    }

    return median;
}

public static void main(String[] args)
{
    add(new Random().ints(1, 100000).boxed());
    System.out.println(median());
}

}

Я получаю следующее исключение:

Exception in thread "main" java.lang.NullPointerException
at hard.Median.lambda$0(Median.java:25)
at hard.Median$$Lambda$2/1929600551.accept(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
at java.util.Random$RandomIntsSpliterator.forEachRemaining(Random.java:1044)
at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at hard.Median.add(Median.java:23)
at hard.Median.main(Median.java:75)

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

Это было полезно?

Решение

Этот

{
    minHeap = new PriorityQueue<>();

    maxHeap = new PriorityQueue<>();
}

является пример инициализатор.Вы можете захотеть

static {
    minHeap = new PriorityQueue<>();

    maxHeap = new PriorityQueue<>();
}

чтобы он выполнялся при инициализации класса.

Однако обратите внимание, что PriorityQueue объекты будут пустыми. peek вернется null в любом случае и < сравнение не получится.Возможно, вы захотите добавить некоторые объекты в PriorityQueue объекты, прежде чем использовать их.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top