-2

我正在尝试在java中实现一个简单的方法,要求如下:

使用分隔符将字符串拆分为列表。如果在分隔符之前放置“\”,则该字符被视为普通字符。例如,如果“;” 用作分隔符,字符串“a;b;cc;\;;;” 将被转换成一个字符串列表:[“a”, “b”, “cc”, “;”, null, null]

我已经编写了所有代码和单元测试,但我不确定是否缺少某些案例。请给我一些改进代码的建议,无论是关于性能或维护(干净的代码)。我也会尝试重构代码。

请给点意见,谢谢。

我只是在学习,不是为了项目。我如何证明实施是正确的?

import java.util.ArrayList;
import java.util.List;

public class SplitStringUtil {

public static List<String> splitStringIntoList(String str, String delimiter) {

    char TRANSLATOR_CHAR = '\\';

    List<String> list = new ArrayList<String>();

    char[] charArr = str.toCharArray();
    char[] delimiterArr = delimiter.toCharArray();

    int i = 0;
    int pos = 0;
    while (i < charArr.length) {
        char temp = charArr[i];
        if (temp == delimiterArr[0]) {
            boolean isDelimiter = true;
            if (delimiterArr.length > 1) {// delimiter's length larger than
                                            // 1
                for (int j = 1; j < delimiterArr.length; j++) {
                    if (delimiterArr[j] != charArr[i + j]) {
                        isDelimiter = false;
                        i += j;
                        break;
                    }
                }
            } else if (i > 0 && charArr[i - 1] == TRANSLATOR_CHAR) {
                isDelimiter = false;
                i++;
                continue;
            }

            if (isDelimiter) {
                char[] tempArr = new char[i - pos];
                System.arraycopy(charArr, pos, tempArr, 0, i - pos);
                tempArr = removeSlashFromCharArr(tempArr, 0, tempArr.length);
                list.add(String.valueOf(tempArr));
                pos = i + delimiter.length();
                i += delimiter.length();

                if (i == charArr.length) {
                    list.add("");
                }

            }
        } else {
            i++;
            if (i == charArr.length) {

                char[] tempArr = new char[i - pos];
                System.arraycopy(charArr, pos, tempArr, 0, i - pos);
                tempArr = removeSlashFromCharArr(tempArr, 0, tempArr.length);
                list.add(String.valueOf(tempArr));
                pos = i + delimiter.length();
                i += delimiter.length();
            }
        }
    }

    return list;
}

public static char[] removeSlashFromCharArr(char[] arr, int start, int end) {

    char[] tempArr = arr.clone();

    int count = 0;
    for (int i = start; i < end; i++) {
        if (tempArr[i] == '\\') {
            count++;
            for (int j = i; j < end - 1; j++) {
                tempArr[j] = tempArr[j + 1];
            }
        }
    }

    char[] resArr = new char[tempArr.length - count];

    System.arraycopy(tempArr, 0, resArr, 0, resArr.length);

    return resArr;
}
}






import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Test;


public class SplitStringUtilTest {

@Test
public void testStringValueOfWithZeroAndZero() {

    char[] arr = { 'a', 'b', 'c' };

    assertEquals(String.valueOf(arr, 0, 0), "");// String.valueOf(charArr,
                                                     // 0, 0) return "" instead
                                                       // of null
    assertEquals(String.valueOf(arr, 0, 1), "a");
//      assertNull(String.valueOf(arr, 0, 0));// fail
}


@Test
public void testNewStringWithNotAssignedCharInside(){
    char[] arr = new char[4];
    arr[0] = 'a';
    arr[2] = 'b';

    char notAssignedChar = '\u0000';

    String s = String.valueOf(arr);

    assertEquals(s,"a\u0000b\u0000");

}

@Test
public void testNormal() {
    String str = "a;b;c";
    List<String> list = SplitStringUtil.splitStringIntoList(str, ";");


    String[] arr = str.split(";");

    assertEquals(arr.length, list.size());

    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testDelimiterHasMoreThanOneChar() {
    String str = "abcd";
    List<String> list = SplitStringUtil.splitStringIntoList(str, "bc");


    String[] arr = str.split("bc");

    assertEquals(arr.length, list.size());

    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test 
public void testWithNoDelimiterExist(){
    String str = "abc";
    String delimiter = ";";

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);
    assertEquals(list.get(0),str);
}

@Test
public void testStartWithDelimiter(){
    String str = ";a;b;c;d";
    String delimiter = ";";

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);

    String[] arr = str.split(delimiter);
    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testEndWithDelimiter(){
    String str = ";a;b;c;d;";
    String delimiter = ";";

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);

    String[] arr = {"","a","b","c","d",""};
    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testStartWithSlash(){
    String str = ";a;b;c\\;;d";
    String delimiter = ";";

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);



    String[] arr = {"","a","b","c;","d"};
    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testWhenSlashIsTheDelimiter(){
    String str = "a\\b\\c";
    String delimiter = "\\";
    String[] arr = {"a","b","c"};

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);

    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testWhenSlashIsTheDelimiterAndStartWithIt(){
    String str = "\\a\\b\\c";
    String delimiter = "\\";
    String[] arr = {"","a","b","c"};

    List<String> list = SplitStringUtil.splitStringIntoList(str, delimiter);

    for(int i=0;i<arr.length;i++){
        assertEquals(arr[i],list.get(i));
    }
}

@Test
public void testRemoveSlashFromCharArr(){

    char[] arr = {'a','b','\\','c','\\','d'};
    char [] target = {'a','b','c','d'};
    char [] res = SplitStringUtil.removeSlashFromCharArr(arr, 0, arr.length);

    for(int i=0;i<target.length;i++){
        assertEquals(target[i],res[i]);
    }
}

@Test
public void testRemoveSlashFromCharArrZero(){

    char[] arr = {'a','b','\\','c','\\','d'};
    char [] target = {'a','b','c','d'};
    char [] res = SplitStringUtil.removeSlashFromCharArr(arr, 0, arr.length);

    for(int i=0;i<target.length;i++){
        assertEquals(target[i],res[i]);
    }
}
}
4

1 回答 1

1

只是为了实际学习。我建议使用标准可用方法,如 String.split(String regex) http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split%28java.lang.String %29 ,将其数组输出更改为 list 并从您的方法中返回该列表,而不是重新发明轮子。

于 2013-11-07T10:59:32.263 回答