ดังนั้นฉันต้องการย้ำสำหรับตัวละครแต่ละตัวในสตริง
ดังนั้นฉันคิดว่า:
for (char c : "xyz")
แต่ฉันได้รับข้อผิดพลาดของคอมไพเลอร์:
MyClass.java:20: foreach not applicable to expression type
ฉันจะทำสิ่งนี้ได้อย่างไร
ดังนั้นฉันต้องการย้ำสำหรับตัวละครแต่ละตัวในสตริง
ดังนั้นฉันคิดว่า:
for (char c : "xyz")
แต่ฉันได้รับข้อผิดพลาดของคอมไพเลอร์:
MyClass.java:20: foreach not applicable to expression type
ฉันจะทำสิ่งนี้ได้อย่างไร
คำตอบ:
วิธีที่ง่ายที่สุดสำหรับการใช้ทุกคนchar
ในString
คือtoCharArray()
:
for (char ch: "xyz".toCharArray()) {
}
สิ่งนี้ช่วยให้คุณกระชับสำหรับแต่ละโครงสร้าง แต่น่าเสียดายString
(ซึ่งไม่เปลี่ยนรูป) ต้องดำเนินการคัดลอกการป้องกันเพื่อสร้างchar[]
(ซึ่งไม่แน่นอน) ดังนั้นจึงมีค่าปรับบางอย่าง
จากเอกสาร :
[
toCharArray()
คืนค่า] อาร์เรย์อักขระที่จัดสรรใหม่ซึ่งความยาวคือความยาวของสตริงนี้และมีเนื้อหาที่ถูกเตรียมใช้งานเพื่อให้มีลำดับอักขระที่แสดงโดยสตริงนี้
มีวิธีการวนซ้ำอย่างละเอียดมากกว่าตัวอักษรในอาร์เรย์ (ปกติสำหรับลูปCharacterIterator
, ฯลฯ ) แต่ถ้าคุณยินดีจ่ายค่าใช้จ่ายtoCharArray()
สำหรับแต่ละคนนั้นจะรัดกุมที่สุด
toCharArray( )
นี้เรียกว่า 3 ครั้ง?
211900000
เวลาที่ใช้ในการทำให้สมบูรณ์for (char c : str.toCharArray()) { }
คือ ~ 250ms และเวลาที่ใช้ในการทำให้เสร็จสมบูรณ์for (char c : charArray) { }
คือ <10ms แน่นอนว่าค่าเวลาเหล่านี้จะขึ้นอยู่กับฮาร์ดแวร์ แต่สิ่งที่ซื้อกลับบ้านก็คือวิธีหนึ่งมีค่าใช้จ่ายสูงกว่าวิธีอื่นอย่างมีนัยสำคัญ
toCharArray()
ไม่ได้อยู่ใน body loop; มันถูกเรียกเพียงครั้งเดียวแล้วลูปจะวนซ้ำแถวนั้น (สำหรับแต่ละลูปนั้นแตกต่างจากลูปทั่วไปfor
ซึ่งประเมินการหยุดเงื่อนไขในแต่ละการวนซ้ำ)
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
}
อีกโซลูชันที่มีประโยชน์คุณสามารถทำงานกับสตริงนี้เป็นอาร์เรย์ของสตริงได้
for (String s : "xyz".split("")) {
System.out.println(s);
}
split()
แม็พกับอักขระ Java มากกว่าหนึ่งตัวซึ่งเป็นกรณีของอีโมติคอนเกือบทั้งหมด ตัวอย่างเช่นรูปแบบของตัวอย่างนี้จะวนซ้ำสี่ครั้งแทนที่จะเป็นสามครั้ง:for (String s : "x😁z".split("")) { System.out.println(s); }
คุณต้องแปลงวัตถุ String เป็นอาร์เรย์ของ char โดยใช้วิธีtoCharArray
() ของคลาส String:
String str = "xyz";
char arr[] = str.toCharArray(); // convert the String object to array of char
// iterate over the array using the for-each loop.
for(char c: arr){
System.out.println(c);
}
ในJava 8เราสามารถแก้ปัญหาได้ดังนี้:
String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));
chars ของเมธอด () จะคืนค่าIntStream
ตามที่กล่าวไว้ในdoc :
ส่งคืนสตรีมของ int ที่ไม่มีการขยายค่าถ่านจากลำดับนี้ อักขระใด ๆ ที่แม็พกับจุดโค้ดตัวแทนจะถูกส่งผ่านโดยไม่ถูกตีความ หากมีการเปลี่ยนแปลงลำดับในขณะที่กระแสกำลังอ่านผลลัพธ์จะไม่ได้กำหนด
forEachOrdered
และไม่ได้forEach
?พฤติกรรมของforEach
คือ nondeterministic อย่างชัดเจนโดยที่การforEachOrdered
ดำเนินการสำหรับแต่ละองค์ประกอบของสตรีมนี้ในลำดับการเผชิญหน้าของสตรีมหากสตรีมมีลำดับการเผชิญหน้าที่กำหนดไว้ ดังนั้นforEach
ไม่รับประกันว่าคำสั่งจะถูกเก็บไว้ ตรวจสอบคำถามนี้เพิ่มเติม
เราสามารถใช้codePoints()
พิมพ์ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม
แต่น่าเสียดายที่ Java ไม่ได้ทำให้การดำเนินการString
Iterable<Character>
สามารถทำได้อย่างง่ายดาย มีStringCharacterIterator
แต่ที่ไม่ได้ใช้Iterator
... ดังนั้นทำด้วยตัวเอง:
public class CharSequenceCharacterIterable implements Iterable<Character> {
private CharSequence cs;
public CharSequenceCharacterIterable(CharSequence cs) {
this.cs = cs;
}
@Override
public Iterator<Character> iterator() {
return new Iterator<Character>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < cs.length();
}
@Override
public Character next() {
return cs.charAt(index++);
}
};
}
}
ตอนนี้คุณสามารถ (ค่อนข้าง) วิ่งได้อย่างง่ายดายfor (char c : new CharSequenceCharacterIterable("xyz"))
...
ถ้าคุณใช้ Java 8 คุณสามารถใช้chars()
ในString
ที่จะได้รับStream
ของตัวละคร แต่คุณจะต้องโยนint
กลับไปchar
เป็นส่งกลับchars()
IntStream
"xyz".chars().forEach(i -> System.out.print((char)i));
ถ้าคุณใช้ Java 8 กับคราสคอลเลกชัน , คุณสามารถใช้CharAdapter
ระดับวิธีการที่มีแลมบ์ดาหรือวิธีการอ้างอิงถึงย้ำกว่าทุกตัวอักษรในส่วนforEach
String
Strings.asChars("xyz").forEach(c -> System.out.print(c));
ตัวอย่างเฉพาะนี้ยังสามารถใช้การอ้างอิงวิธีการ
Strings.asChars("xyz").forEach(System.out::print)
หมายเหตุ: ฉันเป็นคอมมิชชันสำหรับ Eclipse Collections
คุณสามารถใช้แลมบ์ดาได้ในกรณีนี้
String s = "xyz";
IntStream.range(0, s.length()).forEach(i -> {
char c = s.charAt(i);
});
สำหรับ Travers String คุณยังสามารถใช้charAt()
กับสตริงได้
ชอบ :
String str = "xyz"; // given String
char st = str.charAt(0); // for example we take 0 index element
System.out.println(st); // print the char at 0 index
charAt()
เป็นวิธีการจัดการสตริงใน java ซึ่งช่วยในการ Travers สตริงสำหรับตัวละครที่เฉพาะเจาะจง
for (char st: "xyz".toCharArray()) {}
ไหม