Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting objects from an ArrayList based on value of certain fields

I have a Course class, which has fields of various types, with their respective getters and setters, such as:

float percentage
char courseLevel
String courseName
boolean takingNow

I then have an ArrayList of course objects and a method:

public <T> ArrayList<Course> getCourses(int parameterId, T value) {
    ArrayList<Course> res = new ArrayList<Course>();
    switch(parameterId) {
        case COURSE_NAME:
            for(Course c: courseList) {
                if(c.getCourseName().equals(value) {
                    res.add(c)
                }
            }
            break;
        ....
        //rest of the cases
        ....
    }
    return res
}

the method then goes through the ArrayList of courses and compares a certain field based on the parameterId and if the course field equals the passed value it adds it to the to be returned arraylist.

Is there a better way to do this than using generics in this way, which I feel is a very poor coding practice.

like image 877
Andrew Delgadillo Avatar asked Oct 27 '25 17:10

Andrew Delgadillo


1 Answers

As far as I understand it, you want to have a method that returns all courses that match a specified condition.

You might consider looking into lambdas... they look a little funky at first, but they're really powerful and once you get used to it it's pretty easy.

For your example, you might have this:

import java.util.ArrayList;
import java.util.function.Predicate;

class Course {

    float percentage;
    char courseLevel;
    String courseName;
    boolean takingNow;

    public static ArrayList<Course> allCourses;

    public ArrayList<Course> getCourses(Predicate<Course> coursePredicate) {
        ArrayList<Course> toReturn = new ArrayList<>();
        for (Course c : allCourses
                            .stream()
                            .filter(coursePredicate)
                            .toArray(Course[]::new)) {
            toReturn.add(c);
        }
        return toReturn;
    }
}

This means we can call it like so:

getCourses(c -> c.courseLevel != 'B');

meaning all that don't have a course level of 'B' will be returned...

What's going on here? OK. First, we take a collection, and turn it into a "Stream". This allows us to use Predicates (which are just conditions to match on) to filter the stream. Finally, we can convert the filtered Stream back to an array, and then add those elements back into an ArrayList.

The lambda defines that condition. It is just a function that accepts a single argument of type Course. In my example, it would be equivalent to the following:

static boolean isMatch(Course c) {
    return c.courseLevel != 'B';
}

The filter method loops over all the elements in the Stream and if applying the Predicate (the lambda, equiv to the above method) returns true, it's included in its result.

like image 154
Joseph Nields Avatar answered Oct 29 '25 06:10

Joseph Nields



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!