user1659644
user1659644

Reputation: 2973

Java program to alphanumeric sorting objects

Java program to alphanumeric sorting objects

please let me know how could i can get the expected result

Expected output : B2 D1 D2 D14 E2

Actual output : B2 D1 D14 D2 E2

====================================

List<Name> lst = new ArrayList<>();
lst.add(new Name("D",1));
lst.add(new Name("D",14));
lst.add(new Name("D",2));
lst.add(new Name("E",2));
lst.add(new Name("B",2));

Collections.sort(lst, new Comparator<Name>() {

    @Override
    public int compare(Name n1, Name n2) {
        // TODO Auto-generated method stub
        String o1=n1.getNm()+n1.getSeatnum();
        String o2=n2.getNm()+n2.getSeatnum();


         return o1.compareTo(o2);

    }
});

for (Name name : lst) {
    System.out.println(name.getNm()+name.getSeatnum());
}

=================================

public class Name {

    private String nm;
    private int seatnum;

    public int getSeatnum() {
        return seatnum;
    }

    public void setSeatnum(int seatnum) {
        this.seatnum = seatnum;
    }

    public Name(String nm) {
        super();
        this.nm = nm;
    }

    public Name(String nm, int seatnum) {
        super();
        this.nm = nm;
        this.seatnum = seatnum;
    }

    public String getNm() {
        return nm;
    }

    public void setNm(String nm) {
        this.nm = nm;
    }

}

Upvotes: 3

Views: 685

Answers (3)

Elliott Frisch
Elliott Frisch

Reputation: 201439

Yes it's possible, but your compare function needs to first check the String part for equality and then use a numerical comparison for the number part (currently, both are compared lexically). So, you could use something like -

public int compare(Name n1, Name n2) {
    int c = n1.getNm().compareTo(n2.getNm());
    if (c != 0) {
        return c;
    }
    return Integer.valueOf(n1.getSeatnum()).compareTo(n2.getSeatnum());
}

Or in Java 8+ using Comparator.comparing(Function) and Comparator.thenComparing(Function) like

public int compare(Name n1, Name n2) {
    return Comparator.comparing(Name::getNm).thenComparing(Name::getSeatnum)
            .compare(n1, n2);
}

Upvotes: 4

ultimate
ultimate

Reputation: 723

You could rewrite your comparator to work in 2 steps:

Collections.sort(lst, new Comparator<Name>() {
    @Override
    public int compare(Name n1, Name n2) {
        // compare the name part
        int nameCompare = n1.getName().compareTo(n2.getName());
        if(nameCompare != 0)
            return nameCompare;
        // compare the number part
        return n1.getSeatnum() - n2.getSeatnum();
    }
});

If you want to be aware of null values you should add:

Collections.sort(lst, new Comparator<Name>() {
    @Override
    public int compare(Name n1, Name n2) {
        // check for null Name
        if(n1 == null && n2 == null)
            return 0;
        else if(n1 == null)
            return -1;
        else if(n2 == null)
            return 1;

        // check for null in nx.getName()
        if(n1.getName() == null && n2.getName() == null)
            return 0;
        else if(n1.getName() == null)
            return -1;
        else if(n2.getName() == null)
            return 1;

        // compare the name part
        int nameCompare = n1.getName().compareTo(n2.getName());
        if(nameCompare != 0)
            return nameCompare;

        // compare the number part
        return n1.getSeatnum() - n2.getSeatnum();
    }
});

This approach would put null values at the beginning of the list. If you prefer to have them at the end of the list, just swap 1 and -1.

If you additionally want to be case-insensitive, modify the name compare line to:

        int nameCompare = n1.getName().toLowerCase().compareTo(n2.getName().toLowerCase());

Upvotes: 0

Nicolas Albert
Nicolas Albert

Reputation: 2596

Just compare letters then your integers:

public int compare(Name n1, Name n2) {
    // TODO Auto-generated method stub
    int compare = n1.getNm().compareTo(n2.getNm());
    if (compare == 0) {
        return Integer.compare(n1.getSeatnum(), n2.getSeatnum());
    } else {
        return compare;
    }
}

Upvotes: 1

Related Questions