2

I have an arraylist like below:

ArrayList<PhoneNumber> arrayListToSort 

PhoneNumber have following properties

private String number;

private String numberType;

Number type is like MOBILE , HOME , OFFICE

I want to sort arrayListToSort by numberType of each.

I can do this with simple alphebetical order.

But my problem is how to sort the list by follwing order.

  1. MOBILE
  2. HOME
  3. OFFICE
Jonny C
  • 1,943
  • 3
  • 20
  • 36
Chinthaka Dinadasa
  • 3,332
  • 2
  • 28
  • 33

8 Answers8

1

Hey you can try PhonNumberType with enum check below code

 package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

enum PhonNumberType {
    MOBILE, HOME, OFFICE
}

class PhoneNumber implements Comparable<PhoneNumber> {
    private String number;
    private PhonNumberType phonNumberType;

    @Override
    public int compareTo(PhoneNumber o) {
        return this.phonNumberType.compareTo(o.phonNumberType);
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public PhonNumberType getNumberType() {
        return phonNumberType;
    }

    public void setNumberType(PhonNumberType phonNumberType) {
        this.phonNumberType = phonNumberType;
    }


    @Override
    public String toString() {
        return "PhoneNumber [number=" + number + ", phonNumberType=" + phonNumberType + "]";
    }

}

public class T {

    public static void main(String[] args) {
        List<PhoneNumber> test = new ArrayList<PhoneNumber>();
        PhoneNumber pn = new PhoneNumber();
        pn.setNumber("1");
        pn.setNumberType(PhonNumberType.HOME);

        test.add(pn);

        pn = new PhoneNumber();
        pn.setNumber("2");
        pn.setNumberType(PhonNumberType.MOBILE);
        test.add(pn);

        pn = new PhoneNumber();
        pn.setNumber("3");
        pn.setNumberType(PhonNumberType.OFFICE);
        test.add(pn);

        Collections.sort(test);

        System.out.println(test);
    }

}

output is : [PhoneNumber [number=2, phonNumberType=MOBILE], PhoneNumber [number=1, phonNumberType=HOME], PhoneNumber [number=3, phonNumberType=OFFICE]]

Keval
  • 1,857
  • 16
  • 26
0

Your Ranking is no natural order.

To get your goal result, you must define your own Comparator.

By the way, as @Alexis C. says, use an Enum for your numberType

Higune
  • 643
  • 3
  • 13
  • 31
0

Use an enum for that:

public enum NumberType {
    MOBILE,HOME,OFFICE;
}

If your PhoneNumber is comparable:

@Override
public int compareTo(PhoneNumber o) {
    return numberType.compareTo(o.numberType);
}

It will follow the order described in the enum:

MOBILE,HOME,OFFICE
jaypi
  • 223
  • 2
  • 13
0

There are two ways to do this.

Use a Comparator

In this approach, you sort the ArrayList using a custom Comparator.

Here is the Comparator code. Notice how it first tries to sort on numberType, and then number:

public class PhoneNumberComparator implements Comparator<PhoneNumber> {
    @Override
    public int compareTo (PhoneNumber lhs, PhoneNumber rhs) {
        int result = lhs.numberType.compareTo(rhs.numberType);
        if (result == 0) {
            result = lhs.number.compareTo(rhs.number);
        }
        return result;
    }
}

Then you can call:

Comparator c = new PhoneNumberComparator();
arrayListToSort.sort (c)

Now by itself, this won't work completely because the sort of numberType will just be in string order. The most convenient way to impose the ordering is to make numberType an enumeration. Here is the code for that:

public enum NumberType { MOBILE, HOME, OFFICE }

Then the PhoneNumber must be defined so that numberType is a NumberType:

public class PhoneNumber {
    public String number ;
    public NumberType numberType;

    // .......

}

(By the way I would encourage you to also make number and numberType into private variables, and add getter methods, as per the JavaBeans standard.)

Make PhoneNumber Implement Comparable

If you are planning to do this sort often, then instead of writing the Comparator, you should make PhoneNumber implement the Comparable interface:

public class PhoneNumber implements Comparable <PhoneNumber> {
    public String number ;
    public NumberType numberType;

    // .......

    @Override
    public int compareTo (PhoneNumber rhs) {
        int result = this.numberType.compareTo(rhs.numberType);
        if (result == 0) {
            result = this.number.compareTo(rhs.number);
        }
        return result;
    }
}

Then you can just call:

arrayList.sort()

You still need to make NumberType an enum, as discussed in the first approach. The above compareTo() implementation relies on NumberType being Comparable; all enum instances are automatically Comparable.

Notice the similarities and the differences between the Comparator and the compareTo() implementations. A good discussion of Comparator and Comparable can be found here.

sparc_spread
  • 10,643
  • 11
  • 45
  • 59
0

If you make your NumberType enum, not String, its compareTo() method will return result based on order in which enum instances are declared, not alphabetical:

public enum NumberType {
   MOBILE, HOME, OFFICE;
}

MOBILE now is less than HOME and HOME is less than OFFICE. Now you may sort your collection using custom comparator:

list.sort(comparing(PhoneNumber::getNumberType).thenComparing(PhoneNumber::getNumber));
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
0
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;


public class Main {
    public static void arrayListToSort(ArrayList<PhoneNumber> arrayListToSort) {
        Map<String, Integer> phoneTypeToOrder = new HashMap<>();
        phoneTypeToOrder.put("MOBILE", 0); 
        phoneTypeToOrder.put("HOME", 1);
        phoneTypeToOrder.put("OFFICE", 2);

        Collections.sort(arrayListToSort, new Comparator<PhoneNumber>() {

            @Override
            public int compare(PhoneNumber o1, PhoneNumber o2) {
                if (o1 == null || o1.numberType == null) {
                    return -1;
                }
                if (o2 == null || o2.numberType == null) {
                    return 1;
                }
                Integer o1Order = phoneTypeToOrder.get(o1.numberType);
                Integer o2Order = phoneTypeToOrder.get(o2.numberType);
                return o1Order.compareTo(o2Order);
            }

        });
    }
}

class PhoneNumber {
    String number;

    String numberType;
}
JIE WANG
  • 1,875
  • 1
  • 17
  • 27
0

I suggest using a customing "sorting-method" called Comparator. In this Comparator you define a "value" for each your records which will be calculated at runtime. The calculation of this value is entirely up to you. You can for example define that "foo" == 1, "bar" == 2 and "john" == 654. The sorting method of Java will then ask each record for it's "value" and sort accordingly (I think using Quicksort-Algorithm, but I am not sure about this).

Here's a nice little tutorial to get you into this topic and shows how to implement Comparator and Comparable-Interfaces correctly: http://www.tutorialspoint.com/java/java_using_comparator.htm

This one is a bit more indepth: http://www.journaldev.com/780/java-comparable-and-comparator-example-to-sort-objects

Besides: as stated before, use enums for your number-types. not because it's easier (imho) but because it is much faster comparing enums than comparing Strings.

Florian
  • 100
  • 9
0

You can use a TreeSet collection, which sorts the entries.

TreeSet<PhoneNumber> sortedList = new TreeSet<>((PhoneNumber p1, PhoneNumber p2) -> p1.compareTo(p2));

Since you have to define an order for the entries, your PhoneNumber class will have to implement the Comparable interface and you need to override the compareTo() method to say that you will compare on the numberType

public int compareTo(Object o) {
    PhoneNumber p = (PhoneNumber) o;
    return numberType.equals(o.getNumberType())?0:numberType.equals("MOBILE")?-1:1;
}

However, better to use an enum if you want to add more number types in future

kaykay
  • 556
  • 2
  • 7