Effective List Search

I have a situation where I fill in ArrayListwith TransactionEvent. TransactionEventhas the property "transaction identifier". In most cases, each new event has a transaction identifier that exceeds the previous event identifier - however, this is not guaranteed; that is, the data is almost sorted.

My question is this: how can I do a quick search based on a transaction id? My current idea is to call Collections.binarySearch(...), and if that doesn't work, do a linear search. However, I noticed that Javadoc claims that the result of binarySearch undefined is that the data is disordered, so I may have to roll up my own implementation.

Additionally:

  • I tried to use the index map index → ​​transaction ID, but this approach is wrong, because whenever the list item is updated / deleted, I have to rebuild the whole map; those. any winnings are erased by this.
  • This does not apply to premature optimization: it Listis the basis for TableModelbeing executed very slowly at the moment with a large number of lines (100,000).

Any help was appreciated.

+5
source share
11 answers

You can keep the ArrayList sorted by searching for the insertion point as you add each TransactionEvent. Collections.binarySearch returns

, ; (- ( ) - 1). , : list.size(), . , , >= 0 , .

ArrayList add (int index, Object element) , . , .

+3

LinkedHashMap, -, TableModel, ArrayList, - TransactionID.

(, ) , .

+3

ArrayList . 100 000 . , , . ArrayList , , , , BTree 100K .

ArrayList :

  • , ( )
  • , .

(, BTree) , ( ) sqrt (size), .

() BTrees

[] . 1000 ArrayList 7 , 1000000 - 7 . BTree ( 1000 ).

acces, , . , .

, sqrt (size). 100K 150 . ,

+1

, , , - .

, , HashMap ArrayList. HashMap TransactionEvents, TransactionID . HashMap - O (1).

, HashMap , - . , (err ) , .

100 . java OutOfMemoryErrors.

java -Xms<initial heap size> -Xmx<maximum heap size>

:

java -Xms32m -Xmx128m

EDIT:

, SortedMap.

0

. , , . .

0

, , . , , , , O (n + log n).

, wikipedia .

0

. , , - , ArrayList, . . , -

0

, . . :

  • , , ArrayList , ( ), ( -ordered).
  • ArrayList . , , .
0

, . TreeMap , . , . , .

- , map.headSet() k- - . → EventID ( ).

​​

Map<EventID, Event> model = new TreeSet<EventID, Event>();

getValueAt() :

getValueAt(int row, column) {
 eventID = getSortPosition(row);
 Event e = model.headSet(eventID).next();
 return getColumn(e, column);
}

→ ( ). -trival, . , CS, .

:  - , .

ArrayList<Event> orderedEvents = new ArrayList<Event>();
public void insert(Event event) {
 model.put(event.getID(), event);

 // update the 
 model.headSet().addAll(orderedEvents);
}

getValueAt() .

getValueAt(int row, column) {w);
 Event e = orderedEvents.get(row);
 return getColumn(e, column);
}
  • O (n) O (n log n) ( )

, , 100K, :

  • 100 .
  • eventID, , eventID, : sortedMap.headSet(searchFilterID)// 200,
  • , .
0

, . , , . . , , , ArrayList , , .

class TransactionEventStore
{
    private ArrayList<TransactionEvent> byOrder, byId;

    private void insertByOrder(TransactionEvent e) { this.byOrder.add(e); }

    private void insertById(TransactionEvent e)
    {
        for(int i = this.byId.length() - 1; i > 0; i--)
            if(e.getId() > this.byId.get(i).getId())
            {
                this.byId.add(i,e);
                break;
            }
    }

    public void insert(TransactionEvent e)
    {
        this.insertByOrder(e);
        this.insertById(e);
    }
}

, , this.byOrder, id, this.byId.

0

. @Lizzard, , . , . ( O (n) ), .

// sorted events (using natural ordering on eventID)
SortedSet<Event> model = new TreeSet<Event>();
ArrayList<Event> sortedList = new ArrayList<Event>();
Event lowestAddition, additionPrevEntry; // low water mark for insertions

public void insert(Event x) {
 if (x < lowestAddition) {
  Set<Event> headSet = model.headSet(x); // find the insertion point
  additionPrevEntry = headSet.isEmpty()?model.last():headSet.first();  
  lowestAddition = x;
 }

 model.add(x);  // add
}

public void materialize() {
 SortedSet<Event> tailSet = model.tailSet(additionPrevEntry);

 Event firstValue = tailSet.first();    // this element does not change its order
 Integer order = firstValue.getOrder(); // keep order on Event
 for (Event x : tailSet) {
  x.setOrder(order);
  sortedList.set(order, x);
  order++;
 }

 lowestAddition = null; additionPrevEntry = null;
}

swing, , Swing, :

// now your model code uses the array
public Object getValueAt(int row, int col) {
 return getColumn(sortedList.elementAt(row), col);
}

// you can gain significant performance by deferring
// materialization until you acutally need it
public class DeferredJTable extends JTable {
 public void paintComponent(Graphics G, ...) {
  // if you knew what rows in the table were being drawn
  // ahead of time, you could further defer
  materialize();

  super.paintComponent();
 }
}
0

All Articles