The best data structure for quick search, updating and ordering

The problem is as follows

  • I need to track the number of URLs + clicks.
  • I need to be able to quickly update a URL by counting clicks when a user clicks on that URL.
  • I need to quickly get the URL of the top ten URLs.

NOTE. Assuming you cannot use a database.

What is the best data structure to achieve results?

I had thought about using a map before, but the map does not track the order of the top 10 clicks.

+6
source share
5 answers

List<Map.Entry<URL,Integer>>, T - .

  • , T: .
  • T, , URL . , . , , , 10 . T.
+1

, , TreeSet.

TreeSet , . , URL- , , , . TreeSet. /// O (logn)

, .

 TreeSet<URL> treeSet = new TreeSet<URL>(new URLComparator());


class URL {
    private String url;
    int count;

    public URL(String string, int i) {
        url = string;
        count = i;
    }

    @Override
    public int hashCode() {
        return url.hashCode();
    }

    @Override // No need to write this method. Just used it for testing 
    public String toString() {
        return "url : " + url + " ,count : " + count+"\n";
    }

}

. hashcode URL- hashcode URL.

URLComparator. URL-.

class URLComparator implements Comparator<URL> {

    @Override
    public int compare(URL o1, URL o2) {
        return new Integer(o2.count).compareTo(o1.count);
    }

}

TreeSet<URL> treeSet = new TreeSet<URL>(new URLComparator());

treeSet.add(new URL("url1", 12));
treeSet.add(new URL("url2", 0));
treeSet.add(new URL("url3", 5));

System.out.println(treeSet);

: -

[url : url1 ,count : 12
, url : url3 ,count : 5
, url : url2 ,count : 0
]

10 , .

Iterator<URL> iterator = treeSet.iterator();
int count = 0;
while(count < 10 && iterator.hasNext() ){
    System.out.println(iterator.next());
    count++;
}
+1

Map<String, Integer> :

  • key (url) value ( )

  • put URL- , URL-.

  • - 10 entryset

    // create a list out of the entryset of your map
    Set<Map.Entry<String, Integer>> set = map.entrySet();
    List<Map.Entry<String, Integer>> list = new ArrayList<>(set);
    
    // this can be clubbed in another stub to act on top 'N' click counts
    list.sort((o1, o2) -> (o2.getValue()).compareTo(o1.getValue()));
    list.stream().limit(10).forEach(entry -> 
    System.out.println(entry.getKey() + " ==== " + entry.getValue()));
    
0

Map, 10 URL-. o (nlogn) .

:

( 10) HashMap ( LRU) Retrieve/Update o (1). -10 .

:

class UrlAndCountNode{
    String url;
    int count;
    UrlAndCountNode next;
    UrlAndCountNode prev;   
}

:

Map<String, UrlAndCountNode>
0

. , -, sorted , , - ( ) . clicks . , , .

, , , guava multiset .

, :

static class Holder {
    private final String name;

    private final int clicks;

    public Holder(String name, int clicks) {
        super();
        this.name = name;
        this.clicks = clicks;
    }

    public String getName() {
        return name;
    }

    public int getClicks() {
        return clicks;
    }

    @Override
    public String toString() {
        return "name = " + name + " clicks = " + clicks;
    }
}

:

private static List<Holder> firstN(Multiset<Holder> set, int n) {
    return set.stream().limit(n).collect(Collectors.toList());
}

private static void updateOne(Multiset<Holder> set, String urlName, int more) {
    Iterator<Holder> iter = set.iterator();

    int currentClicks = 0;
    boolean found = false;

    while (iter.hasNext()) {
        Holder h = iter.next();
        if (h.getName().equals(urlName)) {
            currentClicks = h.getClicks();
            iter.remove();
            found = true;
        }
    }

    if (found) {
        set.add(new Holder(urlName, currentClicks + more));
    }

}
0

All Articles