|
1 | 1 | package YASL.Collectors;
|
2 | 2 |
|
3 |
| -import java.util.Comparator; |
4 |
| -import java.util.PriorityQueue; |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Collections; |
| 5 | +import java.util.HashMap; |
| 6 | +import java.util.List; |
| 7 | +import java.util.Map; |
5 | 8 | import java.util.stream.Collectors;
|
6 | 9 |
|
7 | 10 | import YASL.CEstimatedItems;
|
8 | 11 | import YASL.CEstimationFor;
|
9 | 12 | import YASL.IEstimationCollector;
|
10 | 13 |
|
11 | 14 | public class KTopCollector<T> implements IEstimationCollector<T> {
|
12 |
| - private final long _K; |
13 |
| - private final PriorityQueue<CEstimationFor<T>> _queue; |
14 |
| - private long _min = 0L; |
| 15 | + private final int _K; |
| 16 | + private long _min = 0L; |
| 17 | + private final List<CEstimationFor<T>> _items; |
| 18 | + private final Map<T, CEstimationFor<T>> _byValue; |
15 | 19 |
|
16 |
| - public KTopCollector(long K) { |
| 20 | + public KTopCollector(int K) { |
17 | 21 | this._K = K;
|
18 |
| - _queue = new PriorityQueue<>(new Comparator<CEstimationFor<T>>() { |
19 |
| - |
20 |
| - @Override |
21 |
| - public int compare(CEstimationFor<T> o1, CEstimationFor<T> o2) { |
22 |
| - return o2.compareTo(o1); |
23 |
| - } |
24 |
| - }); |
| 22 | + _items = new ArrayList<>(); |
| 23 | + _byValue = new HashMap<>(); |
25 | 24 | }
|
26 | 25 |
|
27 | 26 | @Override
|
28 | 27 | public void put(T item, long cnt) {
|
29 | 28 | if (cnt < _min)
|
30 | 29 | return;
|
31 | 30 |
|
32 |
| - CEstimationFor<T> est = new CEstimationFor<>(item, cnt); |
33 |
| - if (_queue.contains(est)) { |
34 |
| - _queue.remove(est); |
| 31 | + CEstimationFor<T> est = _byValue.get(item); |
| 32 | + if (null != est) { |
| 33 | + _items.remove(Collections.binarySearch(_items, est)); |
35 | 34 | }
|
36 |
| - _queue.offer(est); |
37 | 35 |
|
38 |
| - while (_K < _queue.size()) |
39 |
| - _queue.poll(); |
| 36 | + est = new CEstimationFor<T>(item, cnt); |
| 37 | + _byValue.put(item, est); |
| 38 | + int ind = Collections.binarySearch(_items, est); |
| 39 | + _items.add(-(ind + 1), est); |
| 40 | + |
| 41 | + if ((_K * 1.1) < _items.size()) |
| 42 | + fitK(); |
| 43 | + } |
| 44 | + |
| 45 | + private void fitK() { |
| 46 | + while (_K < _items.size()) { |
| 47 | + _byValue.remove(_items.remove(_K).Item); |
| 48 | + } |
40 | 49 |
|
41 |
| - if (_queue.size() == _K) |
42 |
| - _min = _queue.peek().Count; |
| 50 | + if (_items.size() == _K) |
| 51 | + _min = _items.get(_K - 1).Count; |
43 | 52 | }
|
44 | 53 |
|
45 | 54 | @Override
|
46 | 55 | public CEstimatedItems<T> collect() {
|
| 56 | + fitK(); |
47 | 57 | return new CEstimatedItems<>( //
|
48 |
| - _queue.stream() // |
49 |
| - .map(e -> new CEstimationFor<>(e.Item, e.Count)) // |
50 |
| - .sorted() // |
51 |
| - .collect(Collectors.toList()) // |
| 58 | + _items.stream().collect(Collectors.toList()) // |
52 | 59 | );
|
53 | 60 | }
|
54 | 61 | }
|
0 commit comments