Reputation: 61
I have an ArrayList list of objects, say Person
Let's say Person has a boolean attribute of 'eligible'.
I'd like to get a list of index pairs (i,j), such that list.sublist(i,j) has Persons with equal values of eligible. I don't want to modify the list.
Is there an easy way to do this in Java?
Thanks
Upvotes: 2
Views: 2972
Reputation: 4504
You can use LambdaJ to easily extract a list of persons that is eligible.
Upvotes: 0
Reputation: 5569
Consider a flat int[]
holding the change indices, rather than a list of pairs, since you're toggling between true
and false
. Here is a tested implementation using this paradigm, plus generating the sublists using List.subList()
.
import java.util.*;
public class Main
{
public static void main(String[] args) {
List<Person> people =
Arrays.asList(new Person(true), new Person(false),
new Person(true), new Person(true), new Person(false),
new Person(false), new Person(true));
int[] changes = new int[people.size() + 1]; // allow for max changes
Arrays.fill(changes, -1); // if an index is not used, will remain -1
changes[0] = 0;
int change = 1;
boolean eligible = people.isEmpty() ? false : people.get(0).isEligible();
for (int i = 1; i < people.size(); i++) {
Person person = people.get(i);
if (eligible != person.isEligible()) {
changes[change++] = i;
eligible = person.isEligible();
}
}
changes[change] = people.size(); // end of last change segment
List<List<Person>> sublists = new ArrayList<List<Person>>(change);
for (int i = 0; i < change; i++) {
sublists.add(people.subList(changes[i], changes[i + 1]));
}
System.out.println(sublists);
}
}
Note that no copies are made of people
or its elements; the sublists are merely views into the original list. The above code assumes a Person
class defined something like this:
class Person
{
boolean eligible;
Person(boolean eligible) {
this.eligible = eligible;
}
boolean isEligible() {
return this.eligible;
}
@Override
public String toString() {
return "Person(" + isEligible() + ")";
}
}
Upvotes: 0
Reputation: 1819
There is not straight forward solution to your question, no inbuilt Java functionality. But this can help you.
class Person {
public boolean isEligible;
}
ArrayList<Person> persons;
ArrayList<Pair<Integer,Integer>> retList = new ArrayList<>();
int startIndex = -1;
boolean currentSelection;
for (int i = 0; i < persons.size(); i++) {
if (startIndex < 0) {
startIndex = i;
currentSelection = persons.get(i).isEligible;
continue;
}
if (currentSelection != persons.get(i).isEligible) {
retList.add(new Pair<>(startIndex, i - 1));
startIndex = i;
currentSelection = persons.get(i).isEligible;
continue;
}
}
return retList;
Upvotes: 0
Reputation: 8849
If you want to select the persons with eligible="false"
as List. In java 8 you can use lambda expressions to filter list
List<Person> filteredresults = persons.stream()
.filter(p -> p.getEligibilty()==false).collect(Collectors.toList());
Upvotes: 1
Reputation: 11
I'm not sure what you mean by index pairs, but if you just want a list of eligible indexes, you can use a for loop to look to test the eligibility of each element. If eligible, add the index of that person to your other list. This will not modify your original list.
for(int i = 0; i < personList.size(); i++) {
if (personList.get(i).isEligible()) {
otherList.add(i);
}
}
If eligible is private, you will have to write an isEligible() method that simply returns the boolean value.
Upvotes: 0