Guava能够在离散域上定义范围,然后创建表示这些数字的集合。
是否可以创建现代英语拉丁字母字符的范围?
也许this表明这是不可能的,但我并不理解他们对离散域的定义:
离散域始终表示其整个值集 类型;它不能代表部分领域,如“素数整数”, “长度为5的字符串”或“午夜的时间戳”。
长度为5的所有字符串都不是一个离散的集合吗?一组所有可能的拉丁字符都不是离散域的定义吗?
答案 0 :(得分:4)
您的代码中确实需要Range
吗?
也许您可以使用CharMatcher
?它只支持封闭范围,并且有一组有限的操作(和,或者否定),但如果这对你来说足够了,它可能是一个很好的选择。
答案 1 :(得分:3)
由于Guava Ranges必须是连续的,您可能无法使用一个Range,但您当然可以创建多个Range对象并组合它们的set表示来获取范围中值的集合。
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));
答案 2 :(得分:1)
实际上,一切皆有可能,它可能没有意义。甚至“所有长度为5的字符串”都是适当排序的间隔,但是Range
支持Comparable
但不支持Comparator
,您需要首先包装字符串(这会使结果范围很无用):
@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);
}
CharMatcher
已经是一个谓词,并且“universe”是所有字符的集合,很容易将匹配器转换为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();
}
但我怀疑它是否有效。