guava是否支持定义字符范围?

时间:2012-08-17 13:40:36

标签: java guava range

Guava能够在离散域上定义范围,然后创建表示这些数字的集合。

是否可以创建现代英语拉丁字母字符的范围?

也许this表明这是不可能的,但我并不理解他们对离散域的定义:

  

离散域始终表示其整个值集   类型;它不能代表部分领域,如“素数整数”,   “长度为5的字符串”或“午夜的时间戳”。

长度为5的所有字符串都不是一个离散的集合吗?一组所有可能的拉丁字符都不是离散域的定义吗?

3 个答案:

答案 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();
}

但我怀疑它是否有效。