Here's the method. I want to know if I am violating any best practices here or if I am doing something wrong as far as the language is concerned.
这是方法。我想知道我是否违反了这里的任何最佳做法,或者就语言而言我做错了什么。
private List<String> breakStringInChunks(String text, int chunkSize) {
List<String> chunks = new ArrayList<String>();
String temporary = "";
int numberOfChunks = text.length() / chunkSize;
int beginIndex = 0;
int endIndex = 0;
// Add one iteration if numberOfChunks*chunkSize is less than the length of text.
if ((numberOfChunks * chunkSize) < text.length()) {
numberOfChunks++;
}
// Cut strings and add in the list.
for (int i = 0; i < numberOfChunks; i++) {
endIndex+=chunkSize;
if ((i + 1) == numberOfChunks) {
temporary = text.substring(beginIndex);
}
else {
temporary = text.substring(beginIndex, endIndex);
}
beginIndex=endIndex;
chunks.add(temporary);
}
return chunks;
}
7 个解决方案
#1
Briefer still, and avoids potential resizing of the resulting list.
Briefer仍然,并避免可能调整结果列表的大小。
private static List<String> breakStringInChunks(final String text, final int chunkSize) {
final int numChunks = 0 == (text.length() % chunkSize) ? text.length() / chunkSize : 1 + (text.length() / chunkSize);
final List<String> chunks = new ArrayList<String>(numChunks);
for (int startIndex = 0; startIndex < text.length(); startIndex += chunkSize) {
final int endIndex = Math.min(text.length(), startIndex + chunkSize);
chunks.add(text.substring(startIndex, endIndex));
}
return chunks;
}
#2
Unless I'm misunderstanding your intent, it seems like a massive overkill, and uses string creation quite a lot of times, making the algorithm quite inefficient in java, since strings are immutable.
除非我误解你的意图,否则它似乎是一个巨大的矫枉过正,并且使用了很多次字符串创建,使得算法在java中非常低效,因为字符串是不可变的。
Try this:
public List<String> breakStringsInChunks(String text,int chunkSize) {
if (chunkSize<=1) {
throw new IllegalArgumentException("Chunk size must be positive");
}
if (text==null || text.isEmpty()) {
return Collections.emptyList();
}
List<String> chunks= new LinkedList<String>();
int index=0;
int len = text.length();
//guaranteed to succeed at least once since 0 length strings we're taken care of
do {
chunks.add(text.substring(index, Math.min(index + chunkSize, len)));
index+=chunkSize;
} while (index<len);
return chunks;
}
#3
It's a bit verbose, and there is no need to declare the temporary
string at the start of your method, which could make garbage collection a bit slower. The following would be briefer:
它有点冗长,并且不需要在方法的开头声明临时字符串,这可能会使垃圾收集速度变慢。以下是更简洁的:
private List<String> breakStringInChunks(String text, int chunkSize) {
int nChunks = (int)Math.ceil(((double)text.length())/chunkSize));
List<String> chunks = new ArrayList<String>(nChunks);
// Cut strings and add in the list.
for (int i = 0; i < text.length(); i+=chunkSize) {
int endIndex=i+chunksize;
if (endIndex >= text.length()) {
chunks.add(text.substring(i));
} else {
chunks.add(text.substring(i, endIndex));
}
}
return chunks;
}
One good thing about your method and the text above is that because you always call substring() on the original String, Java will only reference the original character array, so it will save you some memory allocations.
关于你的方法和上面的文本的一个好处是,因为你总是在原始String上调用substring(),Java将只引用原始字符数组,因此它将为你节省一些内存分配。
I think the } else {
is a more common coding standard for Java.
我认为} else {是一种更常见的Java编码标准。
#4
public static final List<String> chunk(final String text, final int chunkSize) {
// Figure out how many chunks we are going to make.
final int textLength = text.length();
final int numberOfChunks =
textLength % chunkSize == 0
? textLength / chunkSize
: textLength / chunkSize + 1;
// Create an array list of just the right size.
final ArrayList<String> chunks = new ArrayList<String>(numberOfChunks);
// Do all the chunking but the last one - here we know that all chunks
// are exactly chunkSize long.
for (int i = 0; i < numberOfChunks - 1; i++) {
chunks.add(text.substring(i * chunkSize, (i + 1) * chunkSize));
}
// Add final chunk, which may be shorter than chunkSize, so we use textLength
// as the end index.
chunks.add(text.substring((numberOfChunks - 1) * chunkSize, textLength));
return chunks;
}
#5
Here is my solution. I tried to implement this to be very efficient:
这是我的解决方案。我试图实现这个非常有效:
public static List<String> breakStringInChunks(String text, int chunkSize) {
if (chunkSize < 2) {
throw new IllegalArgumentException("Chunk size must be > 1");
}
if (null == text || text.isEmpty()) {
return Collections.emptyList();
}
List<String> chunks = new ArrayList<String>(1 + (text.length() / chunkSize));
int length = text.length() - (text.length() % chunkSize);
for (int i = 0; i < length;) {
chunks.add(text.substring(i, i += chunkSize));
}
if (length < text.length())
chunks.add(text.substring(length));
return chunks;
}
#6
How about something like this?
这样的事怎么样?
private List<String> breakStringInChunks(String text, int chunkSize)
{
List<String> chunks = new ArrayList<String>();
while (text.length() > 0)
{
if (chunkSize > text.length())
{
chunkSize = text.length();
}
chunks.add(text.substring(0, chunkSize));
text = text.substring(chunkSize);
}
return chunks;
}
#7
Here's mine. Not much different from some of the other answers, but test-driven, fwiw.
这是我的。与其他一些答案没什么不同,但是测试驱动,fwiw。
public class ChunkTest extends TestCase {
public void testEmpty() throws Exception {
assertEquals(0, breakStringInChunks("", 1).size());
}
public void testOneChunk() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, s.length());
assertEquals(s, chunks.get(0));
assertEquals(1, chunks.size());
}
public void testPartialChunk() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, s.length() + 1);
assertEquals(s, chunks.get(0));
assertEquals(1, chunks.size());
}
public void testTwoChunks() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, 2);
assertEquals("ab", chunks.get(0));
assertEquals("c", chunks.get(1));
assertEquals(2, chunks.size());
}
public void testTwoEvenChunks() throws Exception {
String s = "abcd";
List<String> chunks = breakStringInChunks(s, 2);
assertEquals("ab", chunks.get(0));
assertEquals("cd", chunks.get(1));
}
private List<String> breakStringInChunks(String text, int chunkSize) {
if (text.isEmpty())
return Collections.emptyList();
int n = (text.length() + chunkSize - 1) / chunkSize;
List<String> chunks = new ArrayList<String>(n);
for (int i = 0; i < n; ++i)
chunks.add(text.substring(i * chunkSize, Math.min((i + 1) * chunkSize, text.length())));
return chunks;
}
}
#1
Briefer still, and avoids potential resizing of the resulting list.
Briefer仍然,并避免可能调整结果列表的大小。
private static List<String> breakStringInChunks(final String text, final int chunkSize) {
final int numChunks = 0 == (text.length() % chunkSize) ? text.length() / chunkSize : 1 + (text.length() / chunkSize);
final List<String> chunks = new ArrayList<String>(numChunks);
for (int startIndex = 0; startIndex < text.length(); startIndex += chunkSize) {
final int endIndex = Math.min(text.length(), startIndex + chunkSize);
chunks.add(text.substring(startIndex, endIndex));
}
return chunks;
}
#2
Unless I'm misunderstanding your intent, it seems like a massive overkill, and uses string creation quite a lot of times, making the algorithm quite inefficient in java, since strings are immutable.
除非我误解你的意图,否则它似乎是一个巨大的矫枉过正,并且使用了很多次字符串创建,使得算法在java中非常低效,因为字符串是不可变的。
Try this:
public List<String> breakStringsInChunks(String text,int chunkSize) {
if (chunkSize<=1) {
throw new IllegalArgumentException("Chunk size must be positive");
}
if (text==null || text.isEmpty()) {
return Collections.emptyList();
}
List<String> chunks= new LinkedList<String>();
int index=0;
int len = text.length();
//guaranteed to succeed at least once since 0 length strings we're taken care of
do {
chunks.add(text.substring(index, Math.min(index + chunkSize, len)));
index+=chunkSize;
} while (index<len);
return chunks;
}
#3
It's a bit verbose, and there is no need to declare the temporary
string at the start of your method, which could make garbage collection a bit slower. The following would be briefer:
它有点冗长,并且不需要在方法的开头声明临时字符串,这可能会使垃圾收集速度变慢。以下是更简洁的:
private List<String> breakStringInChunks(String text, int chunkSize) {
int nChunks = (int)Math.ceil(((double)text.length())/chunkSize));
List<String> chunks = new ArrayList<String>(nChunks);
// Cut strings and add in the list.
for (int i = 0; i < text.length(); i+=chunkSize) {
int endIndex=i+chunksize;
if (endIndex >= text.length()) {
chunks.add(text.substring(i));
} else {
chunks.add(text.substring(i, endIndex));
}
}
return chunks;
}
One good thing about your method and the text above is that because you always call substring() on the original String, Java will only reference the original character array, so it will save you some memory allocations.
关于你的方法和上面的文本的一个好处是,因为你总是在原始String上调用substring(),Java将只引用原始字符数组,因此它将为你节省一些内存分配。
I think the } else {
is a more common coding standard for Java.
我认为} else {是一种更常见的Java编码标准。
#4
public static final List<String> chunk(final String text, final int chunkSize) {
// Figure out how many chunks we are going to make.
final int textLength = text.length();
final int numberOfChunks =
textLength % chunkSize == 0
? textLength / chunkSize
: textLength / chunkSize + 1;
// Create an array list of just the right size.
final ArrayList<String> chunks = new ArrayList<String>(numberOfChunks);
// Do all the chunking but the last one - here we know that all chunks
// are exactly chunkSize long.
for (int i = 0; i < numberOfChunks - 1; i++) {
chunks.add(text.substring(i * chunkSize, (i + 1) * chunkSize));
}
// Add final chunk, which may be shorter than chunkSize, so we use textLength
// as the end index.
chunks.add(text.substring((numberOfChunks - 1) * chunkSize, textLength));
return chunks;
}
#5
Here is my solution. I tried to implement this to be very efficient:
这是我的解决方案。我试图实现这个非常有效:
public static List<String> breakStringInChunks(String text, int chunkSize) {
if (chunkSize < 2) {
throw new IllegalArgumentException("Chunk size must be > 1");
}
if (null == text || text.isEmpty()) {
return Collections.emptyList();
}
List<String> chunks = new ArrayList<String>(1 + (text.length() / chunkSize));
int length = text.length() - (text.length() % chunkSize);
for (int i = 0; i < length;) {
chunks.add(text.substring(i, i += chunkSize));
}
if (length < text.length())
chunks.add(text.substring(length));
return chunks;
}
#6
How about something like this?
这样的事怎么样?
private List<String> breakStringInChunks(String text, int chunkSize)
{
List<String> chunks = new ArrayList<String>();
while (text.length() > 0)
{
if (chunkSize > text.length())
{
chunkSize = text.length();
}
chunks.add(text.substring(0, chunkSize));
text = text.substring(chunkSize);
}
return chunks;
}
#7
Here's mine. Not much different from some of the other answers, but test-driven, fwiw.
这是我的。与其他一些答案没什么不同,但是测试驱动,fwiw。
public class ChunkTest extends TestCase {
public void testEmpty() throws Exception {
assertEquals(0, breakStringInChunks("", 1).size());
}
public void testOneChunk() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, s.length());
assertEquals(s, chunks.get(0));
assertEquals(1, chunks.size());
}
public void testPartialChunk() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, s.length() + 1);
assertEquals(s, chunks.get(0));
assertEquals(1, chunks.size());
}
public void testTwoChunks() throws Exception {
String s = "abc";
List<String> chunks = breakStringInChunks(s, 2);
assertEquals("ab", chunks.get(0));
assertEquals("c", chunks.get(1));
assertEquals(2, chunks.size());
}
public void testTwoEvenChunks() throws Exception {
String s = "abcd";
List<String> chunks = breakStringInChunks(s, 2);
assertEquals("ab", chunks.get(0));
assertEquals("cd", chunks.get(1));
}
private List<String> breakStringInChunks(String text, int chunkSize) {
if (text.isEmpty())
return Collections.emptyList();
int n = (text.length() + chunkSize - 1) / chunkSize;
List<String> chunks = new ArrayList<String>(n);
for (int i = 0; i < n; ++i)
chunks.add(text.substring(i * chunkSize, Math.min((i + 1) * chunkSize, text.length())));
return chunks;
}
}