Search code examples
javacollectionstreemaptreeset

A TreeSet or TreeMap that allow duplicates


I need a Collection that sorts the element, but does not removes the duplicates.

I have gone for a TreeSet, since TreeSet actually adds the values to a backed TreeMap:

public boolean add(E e) {
    return m.put(e, PRESENT)==null;
}

And the TreeMap removes the duplicates using the Comparators compare logic

I have written a Comparator that returns 1 instead of 0 in case of equal elements. Hence in the case of equal elements the TreeSet with this Comparator will not overwrite the duplicate and will just sort it.

I have tested it for simple String objects, but I need a Set of Custom objects.

public static void main(String[] args)
{       
        List<String> strList = Arrays.asList( new String[]{"d","b","c","z","s","b","d","a"} );      
        Set<String> strSet = new TreeSet<String>(new StringComparator());       
        strSet.addAll(strList);     
        System.out.println(strSet); 
}

class StringComparator implements Comparator<String>
{
    @Override
    public int compare(String s1, String s2)
    {
        if(s1.compareTo(s2) == 0){
            return 1;
        }
        else{
            return s1.compareTo(s2);
        }
    }
}

Is this approach fine or is there a better way to achieve this?

EDIT

Actually I am having a ArrayList of the following class:

class Fund 
{
    String fundCode;
    BigDecimal fundValue;
    .....

    public boolean equals(Object obj) {
    // uses fundCode for equality
    }
}

I need all the fundCode with highest fundValue


Solution

  • I need all the fundCode with highest fundValue

    If that's the only reason why you want to sort I would recommend not to sort at all. Sorting comes mostly with a complexity of O(n log(n)). Finding the maximum has only a complexity of O(n) and is implemented in a simple iteration over your list:

    List<Fund> maxFunds = new ArrayList<Fund>();
    int max = 0;
    for (Fund fund : funds) {
        if (fund.getFundValue() > max) {
            maxFunds.clear();
            max = fund.getFundValue();
    
        }
        if (fund.getFundValue() == max) {
            maxFunds.add(fund);
    
        }
    }
    

    You can avoid that code by using a third level library like Guava. See: How to get max() element from List in Guava