user1255841
user1255841

Reputation: 61

Java: split array list into chunks where objects have an equal attribute value

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

Answers (5)

David Zhao
David Zhao

Reputation: 4504

You can use LambdaJ to easily extract a list of persons that is eligible.

Upvotes: 0

gknicker
gknicker

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

Dunes Buggy
Dunes Buggy

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

Bruce
Bruce

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

Hailey
Hailey

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

Related Questions