2012-08-17 28 views
2

番石榴有能力定義離散域的範圍,然後創建一個代表這些數字的集合。番石榴是否提供任何支持來定義字符範圍?

是否可以在現代英語拉丁字母的字符上創建範圍?

也許this表明,這是不可能的,但我真的不明白他們的離散域的定義:

離散域總是代表着一整套的 類型的值的;它不能表示部分域,如「素數整數」, 「長度爲5的字符串」或「在午夜的時間戳」。

沒有length 5一組離散的所有字符串?一組所有可能的拉丁字符都不是離散域的定義嗎?

+0

'長度爲5的字符串不包含'String'類型的整個值集合。 – 2012-08-17 14:03:43

+0

我認爲它可以被描述爲一個離散的領域,但我想這是它們實現的限制。 – plasma147 2012-08-17 14:54:29

+2

我也被這種語言弄糊塗了,但我相信問題是範圍是按照順序來定義的。您可以定義一個字符串範圍'[「A」,「C」)',這樣就可以包含以任意長度的'A'或'B'開頭的所有字符串。但是,一系列長度爲5 [「A」,「C」)的字符串將包括「蘋果」和「大腦」,但不包括「蘋果」,即使按字母順序排列在兩者之間。應該不可能構造範圍'[A,B]',使得'C不在[A,B]中,而是'A <= C <= B'。 – dimo414 2012-08-17 15:05:45

回答

3

由於番石榴範圍必須是連續的,你可能不能夠使用一個單一的範圍,但你肯定可以創建多個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)); 
4

你真的需要在代碼中使用Range嗎?

也許你可以使用一個CharMatcher?它僅支持封閉範圍,並且有一組有限的操作(和,或否定),但如果這對於您來說是足夠的,它可能是一個很好的選擇。

+0

我希望能夠創建範圍內的值的集合 - 並且CharMatchers不支持。有明顯的非番石榴方式做這個,但我只是想知道是否有番石榴具體的方式。 – plasma147 2012-08-17 14:52:56

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已經是一個謂語用「宇宙」是設置的所有文字,很容易匹配器轉換爲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(); 
} 

但我懷疑它是有效的。

+0

爲什麼建立'allChars'的ImmutableSet然後過濾?從「MIN_VALUE」循環到「MAX_VALUE」並僅添加通過過濾器的字符不會更簡單嗎? – dimo414 2012-08-17 17:03:29

+1

我這麼認爲。我剛剛實現了我的第一個想法......在此期間,我發現建立'allChars'沒有真正簡單的方法。如果有'DiscreteDomains.characters()',會有一個好方法。然而,這一切只是爲了表明這是可能的,而不是我想要真正使用的東西。 – maaartinus 2012-08-17 17:25:32

+1

夠公平的。如果番石榴開發者實施了更多的DiscreteDomains,這將是非常方便的,但是推出自己的[DiscreteDomain ](http://docs.guava-libraries.googlecode.com/git/javadoc/)並不難。 com/google/common/collect/DiscreteDomain.html)。 – dimo414 2012-08-17 17:46:41