最近Reddit上的帖子提出了一个问题:“ 是否存在一种预定义的方法来检查变量值是否包含特定字符或整数? ”基于问题的标题也被以另一种方式问到,“一种检查变量是否包含诸如列表之类的数字的方法或快速方法,例如或('x',2,'B')?” 我不知道标准SDK库中有任何单个方法可以执行此操作(除了使用精心设计的正则表达式),但是在本文中,我使用Guava的CharMatcher和Apache Common Lang的StringUtils类回答了这些问题。
Java的String类确实有一个包含方法 ,如果一个字符被包含在可用于确定String
或者字符的某个明确指定序列中包含的String
。 但是,我不知道在单个可执行语句(不计算正则表达式)中以任何方式询问Java给定的String是否包含指定的一组字符中的任何一个,而不必包含所有字符或以指定顺序包含它们。 Guava和Apache Commons Lang都提供了针对此问题的机制。
Apache Commons Lang (本文中使用的3.1版 )提供了重载的StringUtils.containsAny
方法,可以轻松完成此请求。 这两个重载版本都希望传递给它们的第一个参数是要测试的String
(或更确切地说是CharSequence ),以查看它是否包含给定的字母或整数。 第一个重载版本StringUtils.containsAny(CharSequence,char…)接受零个或多个要测试的char元素,以查看是否有任何元素在第一个参数表示的String中。 第二个重载版本StringUtils.containsAny(CharSequence,CharSequence)期望第二个参数包含要在第一个参数中搜索的所有潜在字符作为单个字符序列。
以下代码清单演示了如何使用这种Apache Commons Lang方法来确定给定的字符串是否包含某些字符。 这三个语句都将通过其断言,因为“受实际事件启发”确实包含“ d”和“ A”,但不包括“ Q”。 因为只需要提供的任何一个字符都返回true,就可以通过true的前两个断言。 第三个断言通过了,因为字符串不包含唯一提供的字母,因此否定断言。
确定字符串包含具有StringUtils的字符
private static void demoStringContainingLetterInStringUtils()
{
assert StringUtils.containsAny("Inspired by Actual Events", 'd', 'A'); // true: both contained
assert StringUtils.containsAny("Inspired by Actual Events", 'd', 'Q'); // true: one contained
assert !StringUtils.containsAny("Inspired by Actual Events", 'Q'); // true: none contained (!)
}
Guava的CharMatcher
也可以按照下一个代码清单所示的类似方式使用。
使用CharMatcher确定字符串包含一个字符
private static void demoStringContainingLetterInGuava()
{
assert CharMatcher.anyOf("Inspired by Actual Events").matchesAnyOf(new String(new char[]{'d', 'A'}));
assert CharMatcher.anyOf("Inspired by Actual Events").matchesAnyOf(new String (new char[] {'d', 'Q'}));
assert !CharMatcher.anyOf("Inspired by Actual Events").matchesAnyOf(new String(new char[]{'Q'}));
}
如果我们特别想确保给定String
/ CharSequence
中的至少一个字符是数字(整数),但是我们不能保证整个字符串都是数字,该怎么办? 可以在上面应用与Apache Commons Lang的StringUtils
相同的方法,唯一的变化是要匹配的字母是数字0到9。这在下一个屏幕快照中显示。
确定字符串包含StringUtils的数字
private static void demoStringContainingNumericDigitInStringUtils()
{
assert !StringUtils.containsAny("Inspired by Actual Events", "0123456789");
assert StringUtils.containsAny("Inspired by Actual Events 2013", "0123456789");
}
番石榴的CharMatcher
具有一种CharMatcher
方式来表达这个问题,即所提供的字符序列是否至少包含一个数字。 这显示在下一个代码清单中。
使用CharMatcher确定字符串包含数字
private static void demoStringContainingNumericDigitInGuava()
{
assert !CharMatcher.DIGIT.matchesAnyOf("Inspired by Actual Events");
assert CharMatcher.DIGIT.matchesAnyOf("Inspired by Actual Events 2013");
}
CharMatcher.DIGIT提供了一种简洁明了的方法来指定我们要匹配的数字。 幸运的是, CharMatcher
提供了许多类似于DIGIT
其他公共字段 ,以便于确定字符串是否包含其他类型的字符。
为了完整起见,我在下一个代码清单中包含了包含上述所有示例的单个类。 此类的main()
函数可以在Java启动器上设置-enableassertions (或-ea
) 标志的情况下运行,并且无需任何AssertionError即可完成。
StringContainsDemonstrator.java
package dustin.examples.strings;
import com.google.common.base.CharMatcher;
import static java.lang.System.out;
import org.apache.commons.lang3.StringUtils;
/**
* Demonstrate Apache Commons Lang StringUtils and Guava's CharMatcher. This
* class exists to demonstrate Apache Commons Lang StringUtils and Guava's
* CharMatcher support for determining if a particular character or set of
* characters or integers is contained within a given
*
* This class's tests depend on asserts being enabled, so specify the JVM option
* -enableassertions (-ea) when running this example.
*
* @author Dustin
*/
public class StringContainsDemonstrator
{
private static final String CANDIDATE_STRING = "Inspired by Actual Events";
private static final String CANDIDATE_STRING_WITH_NUMERAL = CANDIDATE_STRING + " 2013";
private static final char FIRST_CHARACTER = 'd';
private static final char SECOND_CHARACTER = 'A';
private static final String CHARACTERS = new String(new char[]{FIRST_CHARACTER, SECOND_CHARACTER});
private static final char NOT_CONTAINED_CHARACTER = 'Q';
private static final String NOT_CONTAINED_CHARACTERS = new String(new char[]{NOT_CONTAINED_CHARACTER});
private static final String MIXED_CONTAINED_CHARACTERS = new String (new char[] {FIRST_CHARACTER, NOT_CONTAINED_CHARACTER});
private static final String NUMERIC_CHARACTER_SET = "0123456789";
private static void demoStringContainingLetterInGuava()
{
assert CharMatcher.anyOf(CANDIDATE_STRING).matchesAnyOf(CHARACTERS);
assert CharMatcher.anyOf(CANDIDATE_STRING).matchesAnyOf(MIXED_CONTAINED_CHARACTERS);
assert !CharMatcher.anyOf(CANDIDATE_STRING).matchesAnyOf(NOT_CONTAINED_CHARACTERS);
}
private static void demoStringContainingNumericDigitInGuava()
{
assert !CharMatcher.DIGIT.matchesAnyOf(CANDIDATE_STRING);
assert CharMatcher.DIGIT.matchesAnyOf(CANDIDATE_STRING_WITH_NUMERAL);
}
private static void demoStringContainingLetterInStringUtils()
{
assert StringUtils.containsAny(CANDIDATE_STRING, FIRST_CHARACTER, SECOND_CHARACTER);
assert StringUtils.containsAny(CANDIDATE_STRING, FIRST_CHARACTER, NOT_CONTAINED_CHARACTER);
assert !StringUtils.containsAny(CANDIDATE_STRING, NOT_CONTAINED_CHARACTER);
}
private static void demoStringContainingNumericDigitInStringUtils()
{
assert !StringUtils.containsAny(CANDIDATE_STRING, NUMERIC_CHARACTER_SET);
assert StringUtils.containsAny(CANDIDATE_STRING_WITH_NUMERAL, NUMERIC_CHARACTER_SET);
}
/**
* Indicate whether assertions are enabled.
*
* @return {@code true} if assertions are enabled or {@code false} if
* assertions are not enabled (are disabled).
*/
private static boolean areAssertionsEnabled()
{
boolean enabled = false;
assert enabled = true;
return enabled;
}
/**
* Main function for running methods to demonstrate Apache Commons Lang
* StringUtils and Guava's CharMatcher support for determining if a particular
* character or set of characters or integers is contained within a given
* String.
*
* @param args the command line arguments Command line arguments; none expected.
*/
public static void main(String[] args)
{
if (!areAssertionsEnabled())
{
out.println("This class cannot demonstrate anything without assertions enabled.");
out.println("\tPlease re-run with assertions enabled (-ea).");
System.exit(-1);
}
out.println("Beginning demonstrations...");
demoStringContainingLetterInGuava();
demoStringContainingLetterInStringUtils();
demoStringContainingNumericDigitInGuava();
demoStringContainingNumericDigitInStringUtils();
out.println("...Demonstrations Ended");
}
}
Guava和Apache Commons Lang在Java开发人员中非常受欢迎,因为它们提供的方法超出了SDK开发人员通常需要的SDK。 在本文中,我研究了如何使用Guava的CharMatcher
和Apache Commons Lang的StringUtils
进行简洁而富有表现力的测试,以确定提供的字符串中是否存在一组指定字符。