0

In Java, I currently have my PriorityQueue set up to add the objects where they are needed in the list, ideally, I'd want to call a method on all of the moved items, for example:

List = {0,10,20,30,40,50,60,70,80,90,100}.

Add 55

List = {0,10,20,30,40,50,55,60,70,80,90,100}

Objects that would have moved down: {0,10,20,30,40,50} (indexes: 7,8,9,10,11,12)

I only need to worry about the highest 8 items in this list, so, ideally it would only call the method on:

{40,50} (indexes: 7,8)

if anything below that index is changed, I don't need to bother checking it. I've tried doing it by creating a LinkedList, using Collections.sort and cloning the top 8 elements before the next sort. but I continually run into null pointer or and Index out of bounds exception.

Could anyone provide a more generic approach to this problem? My current iteration method:

Hit[] sorted = hitList.toArray(new Hit[hitList.size()]);
    for (int i = sorted.length - 1; i > 0; i--) {
        if (sorted[i] != clone[i]) { // Nullpointer, arrays are not of equal length
            System.out.print("CHANGE AT " + i);
        }
        System.out.println("");
    }

My point is, surely there's a method that avoids this entire conundrum, such as extending a Priority List and overriding add... Which isn't an option because all the useful methods are private.

1
  • PriorityQueue keeps track only of the top element. The order of remaining elements is unspecified. You have to use SortedSet or manually sorted collection. Commented Jun 1, 2014 at 19:58

2 Answers 2

1

I would do it like this:

TreeSet<T> set = new TreeSet<>();

public void add(T t) {
    List<T> oldHead = new ArrayList<>(set).subList(0, Math.min(set.size(), 8));
    set.add(t);
    List<T> newHead = new ArrayList<>(set).subList(0, Math.min(set.size(), 8));
    for (T e : oldHead) {
        int oldIndex = oldHead.indexOf(e);
        int newIndex = newHead.indexOf(e);
        if (oldIndex != newIndex) {
            System.out.println(e + ": " + oldIndex + "->" + newIndex);
        }
    }
}

Make sure duplicated entries are handled as expected.

Sign up to request clarification or add additional context in comments.

1 Comment

After a little tweaking, this method is absolutely perfect. +1 for actually understanding what I meant :P
0

In Java, indexes start from 0 (first element has index 0, second has 1 etc.). In your case 12th element (the last one) has index 11 (not 12 as you wrote), so asking for element with index 12 (i.e. 13th element) causes Null pointer or Index out of bounds exception.

Here's the code after edit:

Hit[] sorted = hitList.toArray(new Hit[hitList.size()]);
for (int i = clone.length - 1; i > 0; i--) {
    if (sorted[i + sorted.length - clone.length] != clone[i]) {
        System.out.print("CHANGE AT " + i);
    }
    System.out.println("");
}

7 Comments

Yeah I know, the issue is really when I'm checking against a cloned array that is not of equal length, What's a simple way to check that? I'll add my current method of iteration.
You can't ask for index 11 of both 12 and 8 elements array. I'll try to figure the solution
Exactly. But again, this is horrible, I'm having to clone an entire array when the pushing is CLEARLY happening on add.
I just edited my answer, try the code (it works only if sorted is larger or equal to clone in array length, otherwise split the operands)
I have no doubt this would work but it seems counter-intuitive to need to clone an array when the order of the list is changing...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.