简体   繁体   中英

Sorting through an array list of objects

I am trying to read data in from a CSV file containing 4 columns to an array list. Let's call the columns a,b,c,d (They each contain integers). Then I would like to sort the array list according to the contents of the rows of a,b,c,d.

So if you are comparing row 1 and 2 for example, if the value of 1d<2d then return a certain value. If 1d=2d then compare 1c to 2c and so on. I am having trouble with finding a way to create an array list that allows me to differentiate and compare each row/column.

public class Speed {
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        readCSV();
    }

    public static void readCSV() throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader("amis.csv"));
        String line = "";
        ArrayList<String> amis = new ArrayList<String>();
        while ((line = br.readLine()) != null) {
            line = line.replaceAll("\"", "");

            amis.add(line);
        }

        amis.remove(0);

        for (String alphabet: amis) {
            Object[] parts = alphabet.split(",");
            Object studentID = (parts[0]);
            Object a = parts[1];
            Object b = parts[2];
            Object c = (parts[3]);
            Object d = parts[4];
            ArrayList<Object> Compare = new ArrayList();

            Compare.add(a);
            Compare.sort(new customComparator());
        }

My custom comparator class

public class customComparator implements Comparator<Object> {
    public int compare(Object o1, Object o2) {
        int a = (Integer) o1;
        int b = (Integer) o2;

        if (a < b) {
            return 1;
        }
        else if(a > b)
            return -1;
        else
            return 0;
    }
}

You should rather create POJO for each string and comparator for it. In the comparator you should compare more "important" columns first and go to less important if previous are equal.

public class Pojo {
private int a;
private int b;
private int c;
private int d;

public int getA() {
    return a;
}

public void setA(int a) {
    this.a = a;
}

public int getB() {
    return b;
}

public void setB(int b) {
    this.b = b;
}

public int getC() {
    return c;
}

public void setC(int c) {
    this.c = c;
}

public int getD() {
    return d;
}

public void setD(int d) {
    this.d = d;
}

public static class PojoComparator implements Comparator<Pojo> {

    @Override
    public int compare(Pojo pojo1, Pojo pojo2) {
        return pojo1==null ? (pojo2==null ? 0:1) :(pojo2==null?-1:
                (pojo1.d!=pojo2.d? pojo1.d-pojo2.d : 
                (pojo1.c!=pojo2.c ? pojo1.c-pojo2.c: 
                (pojo1.b!=pojo2.b? pojo1.b-pojo2.b:
                        pojo1.a-pojo2.a))) );
    }
  }
  }

Let's take a look at your current sorting method

for(String alphabet: amis)
{
    Object[] parts = alphabet.split(",");
    Object studentID = (parts[0]);
    Object a = parts[1];
    Object b = parts[2];
    Object c = (parts[3]);
    Object d = parts[4];
    ArrayList<Object> Compare = new ArrayList();

    Compare.add(a);
    Compare.sort(new customComparator());
}

The most blatant issue is you're creating an ArrayList, Compare, adding/sorting, then discarding it

If you're trying to make a second, sorted list:

List<String> sorted = new ArrayList<String>(amis);
sorted.sort(new CustomComparator());

If you're just trying to sort the original list:

amis.sort(new CustomComparator());

You've gotten fairly close to what you want to do, by making a comparator, but it needs tweaking

Your current implementation stops after it checks the first value, it returns 0 instead of continuing

public class CustomComparator implements Comparator<String>
{
    public int compare(String A, String B)
    {
        String[] as = A.split(",");
        String[] bs = B.split(",");

        int a = Integer.parseInt(a[4]); //column d, as an int
        int b = Integer.parseInt(b[4]);
        if(a < b)
            return 1;
        else
            if(a > b)
                return -1;
            else
            {
                a = Integer.parseInt(a[3]); //column c, as an int
                b = Integer.parseInt(b[3]);
                if(a < b)
                    return -1;
                else
                    if(a > b)
                        return 1;
                    else
                    {
                        a = Integer.parseInt(a[2]); //column b, as an int
                        b = Integer.parseInt(b[2]);
                        if(a < b)
                            return -1;
                        else
                            if(a > b)
                                return 1;
                            else
                            {
                                a = Integer.parseInt(a[1]); //column a, as an int
                                b = Integer.parseInt(b[1]);
                                if(a < b)
                                    return -1;
                                else
                                    if(a > b)
                                        return 1;
                                    else
                                        return 0; //all columns are the same
                            }
                    }
            }
    }
}

Noticing that there is a lot of similar code, we can instead change it into a loop

public int compare(String A, String B)
{
    String[] as = A.split(",");
    String[] bs = B.split(",");

    for(int i = 4; i >= 1; i--) //columns d-a
    {
        int a = Integer.parseInt(a[i]);
        int b = Integer.parseInt(b[i]);
        if(a < b)
            return -1;
        if(a > b)
            return 1;
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM