问题
I have to filter and to sort a ArrayList wíth objects.
- Every object has 2 integer pairs => 4 ints per Object.
- Every value of Column_1 < Column_2 and
- Every value of Column_3 < Column_4.
... so each pair represents a distance.
1.) Distance in 1st(Column_1,Column_2) pair and 2nd(Column_3, Column_4,) pair have to be equal.
2.) if there exists in the list a Obj_1 , whose Column_2 value is equal to Column_1 value+1 of Obj_2 and
3.) if there exists in the list a Obj_1 , whose Column_4 value is equal to Column_3 value+1 of Obj_2
then this objects should be merged to one Object respecting values in each pair. ...minimal values in(Column_1,Column_3) and maximal values(Column_2,Column_4)
Example:
Column_1 Column_2 Column_3 Column_4
----------- before filtering --------------
1. 506 520 771 785
2. 106 110 210 214
3. 502 505 181 184
4. 714 717 270 273
5. 106 110 310 314
6. 111 115 215 219
7. 521 524 767 770
8. 502 505 350 353
9. 100 105 204 209
-----------after filtering----------
1. 100 115 204 219
2. 106 110 310 314
3. 502 505 181 184
4. 714 717 270 273
5. 502 520 767 785
How can this kind of filtering be done in Java?
回答1:
My first approach would be to
- implement
Comparable(or write aComparator) based on the logic described above, - write an
equalsmethod implementing the same logic, - fill the contents of the
ArrayListinto aTreeSet, - iterate over the set to merge adjacent elements when applicable.
The TreeSet will order its elements by natural ordering (or using a provided Comparator).
Refined approach
Unfortunately I failed to notice that distinct objects may contain overlapping intervals, thus items to be merged may not be adjacent. An improvement to the above could be:
- implement
Comparablebased on Columns 1 and 3, - (write an
equalsmethod comparing all columns), - sort the contents of the
ArrayList, - for each element in the list, search for elements fulfilling conditions 2) and 3) above, which can then be merged to the original element. Since the list is ordered, you can use binary search over the sublist after the current item. If the current element is merged with another, Columns 2 and 4 are updated, but 1 and 3 not, so the ordering does not change. The other element can then be removed from the list, and the search repeated with the new values of columns 2 & 4, for the sublist after the removed element.
回答2:
Google collections gives you the option to specify a filter predicate that will operate on all entries and decide which to preserve:
Collections2.filter(yourCollection, new Predicate<YourType>() {
@Override
public boolean apply(YourType param) {
// return whether to retain or remove
}
});
来源:https://stackoverflow.com/questions/3712669/java-extended-collection-filtering