Как отделить от файла с динамическими записями

Я пытаюсь разбить много строк, которые читаются из файла, строка за строкой
Вот часть содержимого файла:

Jack, 50, Aldwynne, Field1, Field2, Field3, Field4, Field5
Goe, 23, Clearden, Field1, Field2, Field3, Field4, Field5
Mike, 33, Marblesilver, Field1, Field2
Lupis, 38, Aldfair, Field1, Field2, Field3
Frey, 21, Verttown, Field1, Field2, Field3, Field4, Field5
Zulian, 45, Fogedge, Field1, Field2, Field3, Field4, Field5

Мой код:

BufferedReader br = new BufferedReader(new FileReader(FILENAME))
String currLine;
while ((currLine = br.readLine()) != null) {
    String []arr = currLine.trim().split("\\s*,[,\\s]*");

String first=arr[0];
String second=arr[1];
String third=arr[2];
String fourth=arr[3];
String fifth=arr[4];
String sixth=arr[5];
String seventh=arr[6];
String eighth=arr[7];

// Next Process
}

Затем я сохраняю каждый из них в переменных. Первые две строки в порядке, но проблема в том, что третья строка сгенерирует ошибку ArrayIndexOutOfBounds, потому что в ней нет 4-го индекса. Следовательно, программа останавливается на 3-й строке

Итак, как установить пустую строку ("") на отсутствующий индекс из строки, длина которой меньше 8. Я хочу, как показано ниже (например: строка № 3)

String first="Mike";
String second="33";
String third="Marblesilver";
String fourth="Field1";
String fifth="Field2";
String sixth="";
String seventh="";
String eighth="";

и так далее. Как мне это сделать ?

проверьте длину arr и назначьте пустую строку, если она меньше ожидаемой

pvpkiran 10.08.2018 17:09

просто используйте n как счетчик и проверьте, если n> = arr.length. Для этих полей установите пустую строку. Как String sixth = (n> = arr.length)? "": Arr [n ++];

xyz 10.08.2018 17:10
1
2
116
3

Ответы 3

Я бы предложил использовать другой массив, чтобы не хранить в соответствии с полем. Что-то вроде моего примера ниже:

public static void main(String args[]){
    String [] arr={"Jack", "50", "Aldwynne", "Field1", "Field2", "Field3", "Field4", "Field5"};
    String []resultArray = new String[1024]; // Any max lenght you want

    for(int i = 0; i< arr.length; i++)
        resultArray[i] = arr[i];
    for(int j = arr.length; j < resultArray.length; j++)
        resultArray[j] = "";
}

Используя resultArray, вы не получите ArrayIndexOutOfBounds, пока максимальная длина массива больше или равна необходимому количеству значений.

Я хотел бы заполнить другие поля пустой строкой. Если вы используете Java 8, вы можете прочитать свой файл следующим образом:

String fileName = "file.txt";
String regex = "\\s*,[,\\s]*";
int maxLength = 8;//This should be know from the beginning 
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
    stream.map(line -> {
        List<String> list = new ArrayList<>(Arrays.asList(line.split(regex)));
        List<String> emptyFields = IntStream.range(0, maxLength - list.size())
                .mapToObj(s -> "")
                .collect(Collectors.toList());
        list.addAll(list.size(), emptyFields);
        return list;
    }).forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

В вашем случае он покажет вам:

[Jack, 50, Aldwynne, Field1, Field2, Field3, Field4, Field5]
[Goe, 23, Clearden, Field1, Field2, Field3, Field4, Field5]
[Mike, 33, Marblesilver, Field1, Field2, , , ]           //note the empty fields in the end
[Lupis, 38, Aldfair, Field1, Field2, Field3, , ]
[Frey, 21, Verttown, Field1, Field2, Field3, Field4, Field5]
[Zulian, 45, Fogedge, Field1, Field2, Field3, Field4, Field5]

Кроме того, я бы создал класс MyObject, который будет содержать эту информацию вместо массива, поэтому ваш код должен выглядеть так:

public class MyObject {

    private String first;
    private String second;
    private String third;
    private String fourth;
    private String fifth;
    private String sixth;
    private String seventh;
    private String eighth;

    //...Constructor, Getters, Setter
}

...
List<MyObject> result = stream.map(line -> {
    List<String> list = new ArrayList<>(Arrays.asList(line.split(regex)));
    List<String> emptyFields = IntStream.range(0, maxLength - list.size())
            .mapToObj(s -> "")
            .collect(Collectors.toList());
    list.addAll(list.size(), emptyFields);
    return list;
}).map(line -> new MyObject(line.get(0),
        line.get(1), line.get(2), line.get(3), line.get(4),
        line.get(4), line.get(5), line.get(6))
).collect(Collectors.toList());
...

Спасибо за ваше решение и предложение, я попробовал, и оно сработало, и это меня смутило: [, я новичок в Java, поэтому мне нужно привыкнуть к нему, кстати, ваше решение менее сложное, чем @ m4gic ??

Henry Lietzberg 11.08.2018 17:11

Вы можете протестировать это @HenryLietzberg, я не могу судить о другом решении, вы можете создать тест и проверить, какое из них быстрее :)

YCF_L 11.08.2018 17:14

например, вы можете сделать это:

BufferedReader br = new BufferedReader(new FileReader(FILENAME));
String currLine;
while ((currLine = br.readLine()) != null) {
    String []readed = currLine.trim().split("\\s*,[,\\s]*");
    String []arr = new String [8];
    Arrays.fill(arr, "");
    System.arraycopy(readed, 0, arr, 0, readed.length);
    ...
    // Next Process
}
// do not forget to close it, in finally block or by using try-with-resources statement
br.close();

Большое спасибо, это работает, на самом деле я попытался объявить в начале новый массив с пустой строкой в ​​качестве его содержимого, затем я понял, что эта функция split уменьшает длину массива. Никогда не думал, что могу просто скопировать результат split в новый массив Еще раз спасибо :)

Henry Lietzberg 11.08.2018 17:07

Другие вопросы по теме