Search code examples
javafastutil

How to sort FastUtil BigList with Collection.sort()


If i have arraylist i can use Collection.sort() what's very effective and fast. But now i have to use BigList to hold much elements of my object type, and i have to sort them by value, From object called JasPlayer kills as int and nickname as String.

I've tried to use Collection.sort() whats the best method to do that but i can't use it like normal List.

private BigList<JasPlayer> playerRankingPlaces;

public BigList<JasPlayer> getRanking() {
    return this.playerRankingPlaces;
}

public void addRankingElement(JasPlayer element) {
    this.playerRankingPlaces.add(element);
}

public void setRanking(BigList<JasPlayer> playerRanking) {
    this.playerRankingPlaces = playerRanking;
}

public void sortRankingList() {
    for(JasPlayer player : JasPlayerUtils.getPlayers()) {
        addRankingElement(player);
        long startTime = System.nanoTime();

           //THERE's Problem, i can't use biglist like normal list :\
        Collections.sort(playerRankingPlaces, Comparator.comparing(Ranking :: getKills).thenComparing(Ranking :: getName));


        long endTime = System.nanoTime() - startTime;
        MessageUtils.sendDebug("Sorting " + playerRankingPlaces.size() + "took " +  endTime / 1e9 + " seconds");
    }
}

private static int getKills(UUID uuid) {
    if(JasPlayerUtils.findByUUID(uuid).isPresent()) {
        return JasPlayerUtils.findByUUID(uuid).get().getKills();
    }
    return 0;
}

private static String getName(UUID uuid) {
    if(JasPlayerUtils.findByUUID(uuid).isPresent()) {
        return JasPlayerUtils.findByUUID(uuid).get().getPlayer().getName();
    }
    return "Brak";
}

Solution

  • I'm pretty sure you are suffering from the XY Problem. Fastutil's BigList is harder to use than normal lists and there is no reason to use it if the number of elements can't exceed Integer.MAX_VALUE.

    If you really need it (say you really have 3000 millions of elements and need to store them in memory as a list) the way I found to sort a BigList is using the static sorting methods at the BigArrays class, mergesort and quicksort. They take as arguments:

    • Starting (inclusive) and ending (exclusive) indexes to sort, i.e 0 and the size of the list
    • a LongComparator , which is an object that given two long indexes compares the elements at these indexes
    • a BigSwapper, which is an object that given two long indexes swaps the elements at these indexes.

    Example:

    import it.unimi.dsi.fastutil.BigArrays;
    import it.unimi.dsi.fastutil.BigList;
    import it.unimi.dsi.fastutil.BigSwapper;
    import it.unimi.dsi.fastutil.longs.LongComparator;
    import it.unimi.dsi.fastutil.objects.ObjectBigArrayBigList;
    
    public class App 
    {
        public static void main( String[] args )
        {
            BigList<String> bigList = new ObjectBigArrayBigList<String>();
            bigList.add("Z");
            bigList.add("X");
            bigList.add("Y");
            bigList.add("A");
            bigList.add("C");
            bigList.add("B");
    
            System.out.println("Biglist before: " + bigList.toString());
    
            LongComparator cmp = (i,j) -> bigList.get(i).compareTo(bigList.get(j));
            BigSwapper swapper = (i,j) -> {
                String tmp = bigList.get(i);
                bigList.set(i, bigList.get(j));
                bigList.set(j, tmp);
            };
    
            BigArrays.mergeSort(0, bigList.size64(), cmp, swapper);
    
            System.out.println("Biglist after : " + bigList.toString());
         }
    }
    

    Output:

    Biglist before: [Z, X, Y, A, C, B]
    Biglist after : [A, B, C, X, Y, Z]