Skip to content

Commit

Permalink
Simplify some of the character predicate code.
Browse files Browse the repository at this point in the history
  • Loading branch information
renggli committed Jan 3, 2015
1 parent 7dbc8f1 commit 6585c58
Showing 1 changed file with 15 additions and 18 deletions.
Expand Up @@ -5,35 +5,31 @@
import java.util.List;

/**
* Internal class to build a {@link CharacterPredicate} from single characters or ranges of
* characters.
* Internal class to build an optimized {@link CharacterPredicate} from single characters
* or ranges of characters.
*/
class CharacterRange {

static CharacterPredicate toCharacterPredicate(List<CharacterRange> ranges) {

// 1. sort the ranges
List<CharacterRange> sortedRanges = new ArrayList<>(ranges);
sortedRanges.sort(new Comparator<CharacterRange>() {
@Override
public int compare(CharacterRange first, CharacterRange second) {
return Character.compare(first.start, second.start);
}
});
sortedRanges.sort(Comparator
.comparing((CharacterRange range) -> range.start)
.thenComparing((CharacterRange range) -> range.stop));

// 2. merge adjacent or overlapping ranges
List<CharacterRange> mergedRanges = new ArrayList<>();
for (CharacterRange currentRange : sortedRanges) {
for (CharacterRange thisRange : sortedRanges) {
if (mergedRanges.isEmpty()) {
mergedRanges.add(currentRange);
mergedRanges.add(thisRange);
} else {
CharacterRange lastRange = mergedRanges.get(mergedRanges.size() - 1);
if (lastRange.stop + 1 >= currentRange.start) {
mergedRanges.set(mergedRanges.size() - 1, new CharacterRange(
lastRange.start < currentRange.start ? lastRange.start : currentRange.start,
lastRange.stop > currentRange.stop ? lastRange.stop : currentRange.stop));
if (lastRange.stop + 1 >= thisRange.start) {
CharacterRange characterRange = new CharacterRange(lastRange.start, thisRange.stop);
mergedRanges.set(mergedRanges.size() - 1, characterRange);
} else {
mergedRanges.add(currentRange);
mergedRanges.add(thisRange);
}
}
}
Expand All @@ -42,9 +38,10 @@ public int compare(CharacterRange first, CharacterRange second) {
if (mergedRanges.isEmpty()) {
return CharacterPredicate.none();
} else if (mergedRanges.size() == 1) {
return mergedRanges.get(0).start == mergedRanges.get(0).stop
? CharacterPredicate.of(mergedRanges.get(0).start)
: CharacterPredicate.range(mergedRanges.get(0).start, mergedRanges.get(0).stop);
CharacterRange characterRange = mergedRanges.get(0);
return characterRange.start == characterRange.stop
? CharacterPredicate.of(characterRange.start)
: CharacterPredicate.range(characterRange.start, characterRange.stop);
} else {
char[] starts = new char[mergedRanges.size()];
char[] stops = new char[mergedRanges.size()];
Expand Down

0 comments on commit 6585c58

Please sign in to comment.