Guava 能够定义离散域的范围,然后创建一个代表这些数字的集合。
是否可以在现代英文拉丁字母的字符上创建范围?
也许这表明这是不可能的,但我并不真正理解他们对离散域的定义:
离散域始终表示其类型的整个值集;它不能表示部分域,例如“素数”、“长度为 5 的字符串”或“午夜时间戳”。
不是所有长度为 5 的字符串都是离散集吗?一组所有可能的拉丁字符不是离散域的定义吗?
你真的需要Range
在你的代码中吗?
也许您可以使用CharMatcher
? 它只支持封闭的范围,并且有一组有限的操作(和,或,否定),但如果这对你来说足够了,它可能是一个不错的选择。
由于 Guava Ranges 必须是连续的,因此您可能无法使用单个 Range,但您当然可以创建多个 Range 对象并组合它们的集合表示以获取范围内的值的集合。
DiscreteDomain<Character> domain = new DiscreteDomain<Character>(){
// Implement DiscreteDomain for Character type
};
Range<Character> lower = Ranges.closed('a','z');
Range<Character> upper = Ranges.closed('A','Z');
HashSet<Character> set = new HashSet<Character>();
set.addAll(lower.asSet(domain));
set.addAll(upper.asSet(domain));
其实,一切皆有可能,只是可能没有意义。即使“所有长度为 5 的字符串”也是适当排序的间隔,但是在Range
support Comparable
but no的情况下Comparator
,您需要先包装字符串(这使得生成的 Range 非常无用):
@RequiredArgsConstructor
private static class WrappedString implements Comparable<WrappedString>, Supplier<String> {
@Override
public String get() {
return value;
}
@Override
public int compareTo(WrappedString o) {
final String s1 = get();
final String s2 = o.get();
return ComparisonChain.start()
.compare(s1.length(), s2.length())
.compare(s1, s2)
.result();
}
@NonNull private final String value;
}
public static Range<WrappedString> rangeOfWrappedStringsOfLength(int length) {
final char[] a = new char[length];
final WrappedString lower = new WrappedString(new String(a));
Arrays.fill(a, Character.MAX_VALUE);
final WrappedString upper = new WrappedString(new String(a));
return Ranges.closed(lower, upper);
}
ACharMatcher
已经是一个谓词,并且“宇宙”是所有字符的集合,很容易将匹配器转换为 a Set
:
private final static ImmutableSet<Character> allChars;
static {
final ImmutableSet.Builder<Character> builder = ImmutableSet.builder();
for (int i=Character.MIN_VALUE; i<=Character.MAX_VALUE; ++i) builder.add((char) i);
allChars = builder.build();
}
public static ImmutableSet<Character> toSet(CharMatcher matcher) {
return FluentIterable.from(allChars).filter(matcher).toImmutableSet();
}
但我怀疑它是否有效。