Làm cách nào để tôi có được các n
ký tự đầu tiên của chuỗi trong Java mà không thực hiện kiểm tra kích thước trước (nội tuyến có thể chấp nhận được) hoặc mạo hiểm IndexOutOfBoundsException
?
Làm cách nào để tôi có được các n
ký tự đầu tiên của chuỗi trong Java mà không thực hiện kiểm tra kích thước trước (nội tuyến có thể chấp nhận được) hoặc mạo hiểm IndexOutOfBoundsException
?
Câu trả lời:
Đây là một giải pháp gọn gàng:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Ý kiến: trong khi giải pháp này là "gọn gàng", tôi nghĩ rằng nó thực sự khó đọc hơn một giải pháp sử dụng if
/ else
theo cách rõ ràng. Nếu người đọc chưa thấy thủ thuật này, anh ta / cô ta phải suy nghĩ kỹ hơn để hiểu mã. IMO, ý nghĩa của mã rõ ràng hơn trong phiên bản if
/ else
. Để biết giải pháp sạch hơn / dễ đọc hơn, hãy xem câu trả lời của @ paxdiablo.
Đừng phát minh lại bánh xe ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc nói:
StringUtils.substring(null, *, *) = null StringUtils.substring("", * , *) = ""; StringUtils.substring("abc", 0, 2) = "ab" StringUtils.substring("abc", 2, 0) = "" StringUtils.substring("abc", 2, 4) = "c" StringUtils.substring("abc", 4, 6) = "" StringUtils.substring("abc", 2, 2) = "" StringUtils.substring("abc", -2, -1) = "b" StringUtils.substring("abc", -4, 2) = "ab"
Như vậy:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
nó không giống như yourString.substring(0, n)
. Cái trước là từ StringUtils
, trong khi cái sau đang sử dụng String.substring
(sẽ đưa ra ngoại lệ nếu chỉ số kết thúc vượt quá độ dài chuỗi).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
không phải là len, đó là Chỉ số kết thúc.
Apache Commons Lang có một StringUtils.left
phương pháp cho việc này.
String upToNCharacters = StringUtils.left(s, n);
Có một lớp câu hỏi về SO đôi khi không có ý nghĩa hoàn hảo, câu hỏi này rất gần gũi :-)
Có lẽ bạn có thể giải thích ác cảm của mình với việc sử dụng một trong hai phương pháp mà bạn đã loại trừ.
Nếu đó chỉ là vì bạn không muốn lấy mã của mình bằng các if
câu lệnh hoặc mã bắt ngoại lệ, thì một giải pháp là sử dụng hàm trợ giúp sẽ chăm sóc nó cho bạn, đại loại như:
static String substring_safe (String s, int start, int len) { ... }
sẽ kiểm tra độ dài trước và hành động tương ứng (trả về chuỗi nhỏ hơn hoặc phần đệm có dấu cách).
Sau đó, bạn không phải lo lắng về nó trong mã của bạn, chỉ cần gọi:
String s2 = substring_safe (s, 10, 7);
thay vì:
String s2 = s.substring (10,7);
Điều này sẽ hoạt động trong trường hợp bạn có vẻ lo lắng (dựa trên nhận xét của bạn cho các câu trả lời khác), không phá vỡ dòng mã khi thực hiện nhiều công cụ xây dựng chuỗi.
String upToNCharacters = String.format("%."+ n +"s", str);
Awful if n
là một biến (vì vậy bạn phải xây dựng chuỗi định dạng), nhưng khá rõ ràng nếu là hằng số:
String upToNCharacters = String.format("%.10s", str);
Sử dụng phương pháp chuỗi con, như sau:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Nếu n lớn hơn độ dài của chuỗi, điều này sẽ đưa ra một ngoại lệ, như một người bình luận đã chỉ ra. Một giải pháp đơn giản là bọc tất cả điều này trong điều kiện if(s.length()<n)
trong else
mệnh đề của bạn , bạn có thể chọn xem bạn chỉ muốn in / trả lại toàn bộ Chuỗi hay xử lý theo cách khác.
Nếu bạn đủ may mắn để phát triển với Kotlin,
bạn có thể sử dụng take
để đạt được mục tiêu của mình.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons làm tôi ngạc nhiên,
StringUtils.abbreviate(String str, int maxWidth)
thêm "..." không có tùy chọn để thay đổi hậu tố.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
nhìn lên không gian trống tiếp theo.
Tôi sẽ rời khỏi đây:
public static String abbreviate(String s, int maxLength, String appendToEnd) {
String result = s;
appendToEnd = appendToEnd == null ? "" : appendToEnd;
if (maxLength >= appendToEnd.length()) {
if (s.length()>maxLength) {
result = s.substring(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd;
}
} else {
throw new StringIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length.");
}
return result;
}