Jon_belt
Jon_belt

Reputation: 105

Sorting ArrayList<Object[]> by column

I'm very new to Java and object oriented programming. I'm trying to sort a 2d arrangement of objects. Currently my code reads a CSV file and puts the each line in a new object, and each object has 6 values relating to the file.

Here is my code:

public static void readFile() {
    String line = "";
    try {
        BufferedReader br = new BufferedReader(new FileReader(Main.filepath));
        while ((line = br.readLine()) != null) {
            String values[] = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");

            String filmName = values[0];
            int filmYear = Integer.parseInt(values[1]);
            String filmRating = values[2];
            String filmGenre = values[3];
            int filmLength = Integer.parseInt(values[4]);
            double filmScore = Double.parseDouble(values[5]);
            Object[] film = {filmName, filmYear, filmRating, filmGenre, filmLength, filmScore};

            fileData.add(film);
        }
    } catch (Exception ex) {
        System.out.println("File Not Found");
    }
}

I'm aware that declaring each variable is ultimately unnecessary, however it makes it easier for me to understand.

I want to sort the array by the filmLength variable using .sort() but I'm not sure how.

Upvotes: 1

Views: 115

Answers (2)

user14766515
user14766515

Reputation:

You can use the List.sort(Comparator) method and pass there a chain of comparators, that sort this list in certain order and direction by certain fields.

// Prepare list of arrays List<Object[]>
Object[] film1 = {"filmName2", 1981, "filmRating1", "filmGenre3", 165, 5.4D};
Object[] film2 = {"filmName5", 1982, "filmRating2", "filmGenre5", 163, 5.5D};
Object[] film3 = {"filmName1", 1983, "filmRating3", "filmGenre4", 163, 5.1D};
Object[] film4 = {"filmName4", 1984, "filmRating4", "filmGenre2", 161, 5.2D};
Object[] film5 = {"filmName3", 1985, "filmRating5", "filmGenre1", 162, 5.3D};
Object[] film6 = {"filmName3", 1980, "filmRating5", "filmGenre1", 162, 5.3D};
Object[] film7 = {"filmName3", 1980, "filmRating5", "filmGenre1", 162, 5.0D};
Object[] film8 = {"filmName2", 1979, "filmRating1", "filmGenre3", 165, 5.4D};

List<Object[]> fileData =
        Arrays.asList(film7, film1, film3, film2, film8, film5, film4, film6);
// Sort list using a chain of comparators.
// In this case you should cast fields to their real types.
fileData.sort(Comparator
        .comparing(e -> (String) ((Object[]) e)[0], Comparator.reverseOrder())
        .thenComparing(e -> (double) ((Object[]) e)[5])
        .thenComparing(e -> (int) ((Object[]) e)[1]));
// Print the list line by line
fileData.stream().map(Arrays::toString).forEach(System.out::println);

// [filmName5, 1982, filmRating2, filmGenre5, 163, 5.5]
// [filmName4, 1984, filmRating4, filmGenre2, 161, 5.2]
// [filmName3, 1980, filmRating5, filmGenre1, 162, 5.0]
// [filmName3, 1980, filmRating5, filmGenre1, 162, 5.3]
// [filmName3, 1985, filmRating5, filmGenre1, 162, 5.3]
// [filmName2, 1979, filmRating1, filmGenre3, 165, 5.4]
// [filmName2, 1981, filmRating1, filmGenre3, 165, 5.4]
// [filmName1, 1983, filmRating3, filmGenre4, 163, 5.1]

Upvotes: 0

Unmitigated
Unmitigated

Reputation: 89204

In keeping with the principles of object-oriented programming, you should create a Film class which could store all six properties. You can implement Comparable<Film> to define a sorting order.

public class Film implements Comparable<Film>{
    private final String filmName, filmRating, filmGenre;
    private final int filmYear, filmLength;
    private final double filmScore;
    public Film(final String filmName, final int filmYear, final String filmRating, final String filmGenre, final int filmLength, final double filmScore){
       this.filmName = filmName;
       this.filmYear = filmYear;
       this.filmRating = filmRating;
       this.filmGenre = filmGenre;
       this.filmLength = filmLength;
       this.filmScore = filmScore;
    }

   @Override
   public int compareTo(final Film o){
      return Integer.compare(this.filmLength, o.filmLength);
   }
}

You can then create a List of Film objects which you can easily sort.

BufferedReader br = new BufferedReader(new FileReader(Main.filepath));
final List<Film> films = new ArrayList<>();
while ((line = br.readLine()) != null) {
    String values[] = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");

    String filmName = values[0];
    int filmYear = Integer.parseInt(values[1]);
    String filmRating = values[2];
    String filmGenre = values[3];
    int filmLength = Integer.parseInt(values[4]);
    double filmScore = Double.parseDouble(values[5]);
    films.add(new Film(filmName, filmYear, filmRating, filmGenre, filmLength, filmScore));
}
Collections.sort(films);//sort

Upvotes: 1

Related Questions