In-memory top ten solution Is there anything wrong with the following implementation of an in-memory top-ten bought products tracker?

public class Main {

    private static List&lt;Integer&gt; topTenItems = Collections.synchronizedList(new ArrayList&lt;Integer&gt;(Collections.nCopies(10, 0)));
    private static List&lt;Integer&gt; topTenScores = Collections.synchronizedList(new ArrayList&lt;Integer&gt;(Collections.nCopies(10, 0)));
    private static ConcurrentMap&lt;Integer,Integer&gt; itemsScores;

    public static void main(String[] args)
    {
        itemsScores = new ConcurrentHashMap&lt;Integer,Integer&gt;();

        for (int i = 0; i &lt; 1000000; i++) 
        {
            Integer boughtItem = new Integer((int)(Math.random() * 100) + 1);
            bought(boughtItem);
        }

        assert isSorted(topTenItems);
        assert isSorted(topTenScores);

        System.out.println("items: " + getTopTen());
        System.out.println("scores:" + topTenScores);


    }

    public static boolean isSorted(List&lt;Integer&gt; l)
    {
     for (int i = 1; i &lt; l.size(); i++)
     {
         if (l.get(i - 1) &lt; l.get(i))
             return false;
     }
     return true;
    }

    public static void bought(Integer itemId)
    {
        Integer oldScore = itemsScores.get(itemId);
        Integer newScore;
        if (oldScore == null) 
            newScore = 1;
        else 
            newScore = oldScore + 1;

        itemsScores.put(itemId,newScore);
        doTopTen(itemId,newScore);
    }


    private static void doTopTen(Integer itemId, Integer newScore) 
    {
        if (topTenItems.contains(itemId)) 
        { // we have this already; up the score, check the position
            int itemIndex = topTenItems.indexOf(itemId);
            if (itemIndex &gt; 0) 
            { // not top already
                if (topTenScores.get(itemIndex - 1) &lt; newScore) 
                {
                    // move to one position above
                    Integer tempProd = topTenItems.get(itemIndex - 1);
                    Integer tempScore = topTenScores.get(itemIndex - 1);
                    topTenItems.set(itemIndex - 1, itemId);
                    topTenScores.set(itemIndex - 1, newScore);
                    topTenItems.set(itemIndex, tempProd);
                    topTenScores.set(itemIndex, tempScore);
                } 
                else 
                { // just update the score
                    topTenScores.set(itemIndex, newScore);
                }
            } 
            else 
            {
                topTenScores.set(0,newScore);
            }
        } 
        else 
        {
            for (int i = 0; i &lt; 10; i++) 
            {
                // left to right
                if (topTenScores.get(i) &lt;= newScore) 
                {
                    topTenItems.add(i, itemId);
                    topTenScores.add(i, newScore);
                    topTenItems.remove(10);
                    topTenScores.remove(10);
                    break;
                }
            }
        }

    }


    public static List&lt;Integer&gt; getTopTen() 
    {
        return topTenItems;
    }
}
Yes.

Actually quite a lot. But it's all easily salvageable.

static. It's all static. Hard to test and impossible to use twice (imagine top-ten of two classes of products). Any mutable static field is a code smell. Just drop it everywhere. Rename main and add a new main creating an instance and calling the original main.
private static ConcurrentMap&lt;Integer,Integer&gt; itemsScores;

This can be initialized inline just like the lists.

public static void main(String[] args)
{

Proper Java style is
public static void main(String[] args) {

This applies to all blocks, not only to methods.

Integer boughtItem = new Integer((int)(Math.random() * 100) + 1);

Don't use Math.random() with some strange arithmetic when you can create a new Random() and write
random.nextInt(100)
Don't use new Integer when you don't need a new instance (you should never need a new instance). Use Integer.valueOf, or just leave it out (autoboxing).

    assert isSorted(topTenItems);

Asserts are fine, but not for this. Checking that the list is sorted is actually the only thing the code does, so it makes no sense to switch it off. So use
   if (!isSorted(topTenItems)) {
        throw new WhateverException(&quot;some message&quot;);
   }

or better: Write a proper test using JUnit or alike.

public static boolean isSorted(List&lt;Integer&gt; l)

This doesn't do what the name promises. I'd expect a sorted list not to change after I call Collections.sort. Your list is descending. Moreover, it must be strictly descending. So the method name should express it.
Checking for strictly descending is wrong, isn't it?

    Integer newScore;
    if (oldScore == null) 
        newScore = 1;
    else 
        newScore = oldScore + 1;

Always use braces. Or better, write
    Integer newScore = oldScore == null ? 1 : oldScore + 1;

It's much shorter and clearer.

    doTopTen(itemId,newScore);

Wouldn't updateTopTen be a better name?

private static void doTopTen(Integer itemId, Integer newScore) ...

This looks very complicated. What's worse:

You're using synchronizedList, so you're assuming concurrent access.
The method itself is not synchronized and it'' probably break.

Imagine you test topTenItems.contains(itemId) and in the meantime another thread(s) change the list. So you're doing something based on a wrong test outcome.
I'm a bit lost
Your items are Integers and you're assuming they're sorted, too. Why should they? What do you need them for?
I might go for something like
// start empty as initially there's nothing in top ten
private final List&lt;Integer&gt; topTenItems = new ArrayList&lt;Integer&gt;();
// no topTenScores

private final Object lock = new Object();

private void updateTopTen(Integer itemId, Integer newScore) {
    synchronized (lock) {
        int index = topTenItems.indexOf(itemId);
        if (index == -1) {
            index = topTenItems.size();
            topTenItems.add(itemId);
        }
        while (index &gt; 0 &amp;&amp; itemsScores.get(index) &gt; itemsScores.get(index-1)) {
            swap(index, index-1);
            index--;
        }
        if (topTenItems.size() &gt; TOP_TEN_SIZE) {
            topTenItems.remove(TOP_TEN_SIZE);
        }
    }
}