나는 문자열이
a.b.c.d
‘.’의 발생 횟수를 계산하고 싶습니다. 관용적 방식으로, 바람직하게는 하나의 라이너.
(이전에는 모든 사람들이 루프를 사용하지 않고 응답하려고하는 이유가 궁금한 경우를 대비하여이 제약 조건을 “루프없이”로 표현했습니다.)
답변
이것에 대한 나의 ‘아이디 오 메틱 원 라이너’는 다음과 같습니다.
int count = StringUtils.countMatches("a.b.c.d", ".");
이미 commons lang 에있을 때 직접 작성해야하는 이유는 무엇 입니까?
이를위한 Spring Framework의 oneliner는 다음과 같습니다.
int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");
답변
이건 어때요. 아래에 정규 표현식을 사용하지 않으므로 다른 솔루션보다 빠르며 루프를 사용하지 않습니다.
int count = line.length() - line.replace(".", "").length();
답변
다른 답변과 하나의 라이너를 사용 하여이 작업을 수행하는 모든 방법을 요약하면 다음과 같습니다.
String testString = "a.b.c.d";
1) Apache Commons 사용
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
2) 스프링 프레임 워크 사용
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
3) 바꾸기 사용
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
4) replaceAll 사용 (사례 1)
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
5) replaceAll 사용 (사례 2)
int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
6) 분할 사용
int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);
7) Java8 사용 (사례 1)
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
8) Java8 (case 2 )을 사용하면 case 1보다 유니 코드에 더 좋습니다.
long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);
9) StringTokenizer 사용
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);
코멘트에서 : StringTokenizer, abcd의 경우 작동하지만 a … bc … d 또는 … abcd 또는 a …. b …… c ….. d에주의하십시오. … 등이 작동하지 않습니다. 그냥 계산됩니다. 한 번만 문자 사이
github에 대한 추가 정보
성능 테스트 ( JMH 사용 , 모드 = AverageTime, 0.010
다음보다 우수 0.351
) :
Benchmark Mode Cnt Score Error Units
1. countMatches avgt 5 0.010 ± 0.001 us/op
2. countOccurrencesOf avgt 5 0.010 ± 0.001 us/op
3. stringTokenizer avgt 5 0.028 ± 0.002 us/op
4. java8_1 avgt 5 0.077 ± 0.005 us/op
5. java8_2 avgt 5 0.078 ± 0.003 us/op
6. split avgt 5 0.137 ± 0.009 us/op
7. replaceAll_2 avgt 5 0.302 ± 0.047 us/op
8. replace avgt 5 0.303 ± 0.034 us/op
9. replaceAll_1 avgt 5 0.351 ± 0.045 us/op
답변
조만간 무언가 가 반복되어야합니다. 다음과 같은 것을 사용하는 것보다 (매우 간단한) 루프를 작성하는 것이 훨씬 간단합니다.split
필요한 것보다 훨씬 강력한 합니다.
반드시 루프를 별도의 방법으로 캡슐화하십시오. 예 :
public static int countOccurrences(String haystack, char needle)
{
int count = 0;
for (int i=0; i < haystack.length(); i++)
{
if (haystack.charAt(i) == needle)
{
count++;
}
}
return count;
}
그런 다음 기본 코드에 루프가 필요하지 않지만 루프가 어딘가에 있어야합니다.
답변
나는 Mladen과 비슷한 아이디어를 가지고 있었지만 그 반대는 …
String s = "a.b.c.d";
int charCount = s.replaceAll("[^.]", "").length();
println(charCount);
답변
String s = "a.b.c.d";
int charCount = s.length() - s.replaceAll("\\.", "").length();
ReplaceAll ( “.”)은 모든 문자를 대체합니다.
PhiLho의 솔루션 은 ReplaceAll ( “[^.]”, “”)을 사용합니다. [.]는 ‘any character’가 아닌 ‘dot’문자를 나타내므로 이스케이프 할 필요가 없습니다.
답변
내 ‘아이디 오 매틱 원 라이너’솔루션 :
int count = "a.b.c.d".length() - "a.b.c.d".replace(".", "").length();
StringUtils를 사용하는 솔루션이 왜 허용되는지 모릅니다.