Javaにおける文字列プログラム
日本語では、次のように言い換えられます:「Stringクラスは、Javaプログラミングで最も広く使われているクラスです。そのため、Javaの面接ではStringプログラムを使用して、コーディングのスキルを確認します。」
Javaでの文字列プログラム
私はここで、Javaの文字列プログラムを提供しています。これらの問題を自分で解いてから答えを確認し、より良い方法で学習するようにしてください。私はJavaで導入された最新の機能、例えばStream、ラムダ式、関数インターフェースなどを使用しようとしています。
文字列内の異なる文字とその数を取得する方法は何ですか?
package com.scdev.java.string;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class DistinctCharsCount {
public static void main(String[] args) {
printDistinctCharsWithCount("abc");
printDistinctCharsWithCount("abcab3");
printDistinctCharsWithCount("hi there, i am scdev");
}
private static void printDistinctCharsWithCount(String input) {
Map<Character, Integer> charsWithCountMap = new HashMap<>();
// using Map merge method from Java 8
for (char c : input.toCharArray())
charsWithCountMap.merge(c, 1, Integer::sum);
System.out.println(charsWithCountMap);
// another way using latest Java enhancements and no for loop, a bit complex though
List<Character> list = input.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
list.stream().forEach(c -> charsWithCountMap.merge(c, 1, Integer::sum));
System.out.println(charsWithCountMap);
}
}
Javaプログラムを作成して、文字列を逆にする。
文字列を反転させる方法はいくつかあります。一般的なものの一部は次のとおりです:
- StringBuilder/StringBuffer reverse() method
- Using char/byte array and traverse in reverse direction and populate the result string
ただし、入力の文字列の内容が確実でない場合は、常にStringBuilderの組み込みのreverse()メソッドを使用してください。なぜなら、charおよびbyte配列を使用すると、意図しない結果が生じる可能性があるからです。この点については、「Javaで文字列を逆にする」の記事で詳細な説明を提供しています。
package com.scdev.java.string;
public class ReverseAString {
public static void main(String[] args) {
reverseInputString("abc");
reverseInputString("ç©∆˙¨˚ø"); //special chars
}
private static void reverseInputString(String input) {
StringBuilder sb = new StringBuilder(input);
String result = sb.reverse().toString();
System.out.println(result);
}
}
文字列が回文であるかを確認する方法
回文文字列とは、その逆も同じ文字列であるものです。したがって、入力された文字列を反転させて、それらが等しいかどうかをチェックすることができます。または、StringのcharAt(int index)メソッドを使用して、回文文字列を確認することもできます。
package com.scdev.java.string;
public class PalindromeString {
public static void main(String[] args) {
checkPalindromeString("abc");
checkPalindromeString("abcba");
checkPalindromeString("ç∂©∂ç");
}
private static void checkPalindromeString(String input) {
boolean result = true;
int length = input.length();
for(int i=0; i < length/2; i++) {
if(input.charAt(i) != input.charAt(length-i-1)) {
result = false;
break;
}
}
System.out.println(input + " is palindrome = "+result);
}
}
与えられた文字列から特定の文字の出現をすべて削除する方法は?
Stringクラスには削除機能はありませんが、この場合はreplaceAll()を使用することができます。以下は、それを行う方法を示した簡単なプログラムです。
package com.scdev.java.string;
public class RemoveCharFromString {
public static void main(String[] args) {
removeCharFromString("abcbcdjfkd", 'c');
removeCharFromString("Pankaj", 'a');
removeCharFromString("ç∂©∂ç", '©');
}
private static void removeCharFromString(String input, char c) {
String result = input.replaceAll(String.valueOf(c), "");
System.out.println(result);
}
}
文字列がプログラム上でイミュータブルであることをどのように証明するか?
私たちは、JavaではStringが不変(immutable)であることを知っていますが、新しい開発者はまだこれに混乱します。この混乱の理由を理解しようとしてみましょう。
String s1 = "Java";
s1 = "Python";
上記のコードスニペットでは、s1の値が変更され、それはStringオブジェクトです。では、どのようにしてStringが不変であると言えるのでしょうか?理解するために最も重要なポイントは、Javaで文字列が作成される方法です。文字列リテラルを使用して文字列を作成する場合、元の文字列の値は変更されません。代わりに、文字列プール内に新しい文字列が作成され、変数の参照が変更されます。したがって、元の文字列の値は変更されず、それが文字列の不変性の理由です。以下のプログラムは、私たちの主張を証明しています。概念を正しく理解するためにコメントを読んでください。
package com.scdev.java.string;
public class StringImmutabilityTest {
public static void main(String[] args) {
String s1 = "Java"; // "Java" String created in pool and reference assigned to s1
String s2 = s1; //s2 is also having the same reference to "Java" in the pool
System.out.println(s1 == s2); // proof that s1 and s2 have same reference
s1 = "Python";
//s1 value got changed above, so how String is immutable?
//well, in above case a new String "Python" got created in the pool
//s1 is now referring to the new String in the pool
//BUT, the original String "Java" is still unchanged and remains in the pool
//s2 is still referring to the original String "Java" in the pool
// proof that s1 and s2 have different reference
System.out.println(s1 == s2);
System.out.println(s2);
// prints "Java" supporting the fact that original String value is unchanged, hence String is immutable
}
}
文字列内の単語の数を数えるプログラムを作成してください。
このプログラムの単純な解決策は、input.split(” “).length ですが、文字列が適切にフォーマットされておらず、先頭や末尾にスペースが含まれ、重複した複数のスペースやタブがある場合は機能しません。幸いなことに、String split() 関数は正規表現を引数として受け取ることができるため、文字列内の単語の数を数えるためにそれを使用することができます。
package com.scdev.java.string;
public class CountNumberOfWordsInString {
public static void main(String[] args) {
countNumberOfWords("My name is Pankaj");
countNumberOfWords("I Love Java Programming");
countNumberOfWords(" This is not properly formatted line ");
}
private static void countNumberOfWords(String line) {
//System.out.println(line.split(" ").length); //won't work with tabs and multiple spaces
String trimmedLine = line.trim();
int count = trimmedLine.isEmpty() ? 0 : trimmedLine.split("\\s+").length;
System.out.println(count);
}
}
同じ文字で作成された2つの文字列を確認するプログラムを書いてください。
最初に、入力された文字列から文字のセットを作成する必要があります。その後、セットのequals()メソッドを使用して、それらが同じ文字を含んでいるかどうかを確認します。以下は、二つの文字列が同じ文字で作成されたかどうかを確認するための簡単なプログラムです。
package com.scdev.java.string;
import java.util.Set;
import java.util.stream.Collectors;
public class CheckSameCharsInString {
public static void main(String[] args) {
sameCharsStrings("abc", "cba");
sameCharsStrings("aabbcc", "abc");
sameCharsStrings("abcd", "abc");
sameCharsStrings("11", "1122");
sameCharsStrings("1122", "11");
}
private static void sameCharsStrings(String s1, String s2) {
Set<Character> set1 = s1.chars().mapToObj(c -> (char) c).collect(Collectors.toSet());
Set<Character> set2 = s2.chars().mapToObj(c -> (char) c).collect(Collectors.toSet());
System.out.println(set1.equals(set2));
}
}
2つの文字列のユーザー入力を読み取り、最初の文字列に2番目の文字列が含まれているかどうかを確認しますか?
これは簡単なプログラムで、指定した文字列がこの文字列の一部かどうかを確認するために、Stringのcontains()メソッドを使うことができます。ただし、ユーザーの入力を読み取るためにScannerクラスを使用する必要があります。
package com.scdev.java.string;
import java.util.Scanner;
public class StringContainsSubstring {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter First String:");
String s1 = scanner.nextLine();
System.out.println("Enter Second String:");
String s2 = scanner.nextLine();
scanner.close();
boolean result = stringContainsSubstring(s1, s2);
System.out.println(s1+" contains "+s2+" = "+result);
}
private static boolean stringContainsSubstring(String string, String substring) {
boolean result = false;
result = string.contains(substring);
return result;
}
}
上記のプログラムのサンプル出力です。
Enter First String:
Pankaj
Enter Second String:
an
Pankaj contains an = true
三つ目の変数を使用せずに、2つの文字列を交換する方法はありますか?
私たちはStringのsubstring()メソッドを使ってこれを行うことができます。これを示すための簡単なコードスニペットを以下に示します。
String s1 = "abc";
String s2 = "def";
s1 = s1.concat(s2);
s2 = s1.substring(0,s1.length()-s2.length());
s1 = s1.substring(s2.length());
もし私たちがそれを行うための関数を書かなければならない場合はどうでしょうか?文字列は不変なので、メソッド内の文字列参照の値の変更は、メソッドが終了するとすぐに消えてしまいます。また、Javaではメソッドから複数のオブジェクトを返すことはできません。したがって、入力文字列を保持するためにContainerを作成し、上記のロジックをメソッド内で実行する必要があります。以下のコードは、これがどのように行われるかを示しています。複雑に見えるかもしれませんが、ロジックは上記と同じです。
package com.scdev.java.string;
import java.util.Scanner;
public class SwapTwoStrings {
public static void main(String[] args) {
Container container = new Container();
Scanner scanner = new Scanner(System.in);
System.out.println("Enter First String:");
container.setFirstString(scanner.nextLine());
System.out.println("Enter Second String:");
container.setSecondString(scanner.nextLine());
scanner.close();
System.out.println(container);
container = swapStrings(container);
System.out.println(container);
}
private static Container swapStrings(Container container) {
container.setFirstString(container.getFirstString().concat(container.getSecondString())); //s1 = s1+s2
container.setSecondString(container.getFirstString().substring(0, container.getFirstString().length()-container.getSecondString().length())); // s2=s1
container.setFirstString(container.getFirstString().substring(container.getSecondString().length()));
return container;
}
}
class Container{
private String firstString;
private String secondString;
public String getFirstString() {
return firstString;
}
public void setFirstString(String firstString) {
this.firstString = firstString;
}
public String getSecondString() {
return secondString;
}
public void setSecondString(String secondString) {
this.secondString = secondString;
}
@Override
public String toString() {
return "First String = "+firstString+", Second String = "+secondString;
}
}
サンプルの出力:
Enter First String:
Java
Enter Second String:
Python
First String = Java, Second String = Python
First String = Python, Second String = Java
入力された文字列から最初の非繰り返し文字を見つけるプログラムを作成してください。
package com.scdev.java.string;
import java.util.ArrayList;
import java.util.List;
public class FindNonRepeatingChar {
public static void main(String[] args) {
System.out.println(printFirstNonRepeatingChar("abcaabcdedxy"));
System.out.println(printFirstNonRepeatingChar("abca"));
System.out.println(printFirstNonRepeatingChar("aaa"));
}
private static Character printFirstNonRepeatingChar(String string) {
char[] chars = string.toCharArray();
List<Character> discardedChars = new ArrayList<>();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (discardedChars.contains(c))
continue;
for (int j = i + 1; j < chars.length; j++) {
if (c == chars[j]) { // match found
discardedChars.add(c);
break;
} else if (j == chars.length - 1) { // no match found till end
return c;
}
}
}
return null;
}
}
文字列が数字だけで構成されているかをチェックする方法は2つありますか?
文字列が数値かどうかを確認するために、正規表現を使用することができます。別の方法は、それをLong型にパースし、もし非数値の文字列ならばNumberFormatExceptionが発生します。
package com.scdev.java.string;
public class CheckIfStringContainsDigitsOnly {
public static void main(String[] args) {
digitsOnlyString("111");
digitsOnlyString("111a 1");
digitsOnlyString("111 222");
digitsOnlyString("111L");
}
private static void digitsOnlyString(String string) {
if(string.matches("\\d+")) System.out.println("Digit Only String ::"+string);
try {
long l = Long.parseLong(string);
System.out.println("Digit Only String ::"+string);
}catch(Exception e){
System.out.println("Non Digit Only String ::"+string);
}
}
}
文字列のディープコピーの方法は?
文字列は不変なので、ディープコピーまたはシャローコピーを心配する必要はありません。単純に代入演算子(=)を使用して、一つの文字列を別の文字列にコピーすることができます。詳細は「Java String copy」を読んでください。
私のGitHubのリポジトリから、例をダウンロードすることができます。