I have got a List student with a class Student with variables Int studentId, String name,Boolean fullTime.
I want to filter and create a new list with list of only name of fulltime student(where fullTime is True) from List student i already have.
I have got a List student with a class Student with variables Int studentId, String name,Boolean fullTime.
I want to filter and create a new list with list of only name of fulltime student(where fullTime is True) from List student i already have.
Simplest approach in my opinion
List<String> filteredNames = new ArrayList<>();
for(Student student : listStudents) {
if(student.isFulltime()) {
filteredNames.add(student.getName());
}
}
private class Student{
int studentID;
String name;
boolean fulltime = false;
public Student(int studentID, String name, boolean fulltime) {
this.studentID = studentID;
this.name = name;
this.fulltime = fulltime;
}
public boolean getFullTime() {
return fulltime;
}
}
private ArrayList<Student> getFullTimeStudents(ArrayList<Student> arrayList) {
ArrayList<Student> fulltimeStudents = new ArrayList<Student>();
for (Student student : arrayList) {
if (student.getFullTime()) {
fulltimeStudents.add(student);
}
}
return fulltimeStudents;
}
The other answers are definitely shorter and will get the job done with the least lines of code. But it's interesting to think about this problem more generically. More and more I prefer to take a functional approach. If you look at your problem from a functional approach you want to perform two basic operations. First you want to take a list of one type and transform it into a list of another type. This operation is known as map. Then you want to produce another list that contains a subset of that list based on some criteria. This is called filter. There are lot of libraries that add functional type operations to Java, like Guava, and Java 8 adds those operations directly to collections. But for a simple and dirty example you can do this yourself in Java 7 (that works on Android):
First I create a static helper class called Lists. The basic idea of a function is to take one or more inputs and produce an output. So we define a function that can accept an input of some type and produces an output of some other type. We make it as generic as possible:
public interface Func1<T, R> {
R call(T t1);
}
call() is how you use the function. It's called Func1 because it takes 1 input. You can make any number of functions that accept multiple inputs, but in your case we just need Func1. Func2 would look like this, for example:
public interface Func2<T1, T2, R> {
R call(T1 t1, T2 t2);
}
and so on.
So in your case, you want to apply map and filter to your list of Student. You can apply them in any order but for me it makes sense to filter then map.
so here is the filter operation:
public static <T> List<T> filter(List<T> orig, Func1<? super T, Boolean> func) {
List<T> ret = new ArrayList<>();
for(T obj : orig) {
if(func.call(obj)) {
ret.add(obj);
}
}
return ret;
}
this is doing the same work that others have suggested, in a more generic way. Anything that meets the criteria defined in the function's call method will be added to the returned list.
finally we have map:
public static <T1, T2> List<T2> map(List<T1> orig, Func1<? super T1, T2> mapFunc) {
List<T2> ret = new ArrayList<>();
for(T1 obj : orig) {
ret.add(mapFunc.call(obj));
}
return ret;
}
Again this is just a generic version of previous answers. All of the work will be happening in the call method of the mapFunc that you define.
So the complete class looks like this:
class Lists {
public interface Func1<T, R> {
R call(T t1);
}
public static <T> List<T> filter(List<T> orig, Func1<? super T, Boolean> func) {
List<T> ret = new ArrayList<>();
for(T obj : orig) {
if(func.call(obj)) {
ret.add(obj);
}
}
return ret;
}
public static <T1, T2> List<T2> map(List<T1> orig, Func1<? super T1, T2> mapFunc) {
List<T2> ret = new ArrayList<>();
for(T1 obj : orig) {
ret.add(mapFunc.call(obj));
}
return ret;
}
}
and you use it like this:
// students is List<Student>
List<Student> filteredStudents = Lists.filter(students, new Func1<Student, Boolean>() {
@Override
public Boolean call(Student s) {
return s.getFullTime();
}
});
List<String> filteredNames = Lists.map(filteredStudents, new Func1<Student, String>() {
@Override
public String call(Student s) {
return s.getName();
}
});
It's very verbose to do this in Java but the concepts are interesting. Java 8 has a lot of these concepts built-in and uses closures so there's a lot less typing. If this interests you you should also check out RxJava, it really opens up new possibilities and I find it ideal for Android where an enormous amount of work is spent doing asynchronous operations.