Подскажите пожалуйста, как записать большой (5000 строк) ArrayList<String[]>
в файл через разделитель. String[]
состоит из 13 элементов.
Сейчас делаю так, перебираю все строки и добавляю между ними разделители, потом записываю в файл.. Но на 5000 строк уходит до 20 секунд, это очень долго..
"﹀" - это у меня разделители в текстовом файле..
ArrayList<String[]> myPoints;
...
public void mySavePoints(final String file_name) {
String txt = ""; //составляем текст в файле
if (myPoints.size() > 0) {
for (int i = 0; i < myPoints.size(); i++) {
txt = txt + myPoints.get(i)[0] + "﹀" +
myPoints.get(i)[1].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[2] + "﹀" +
myPoints.get(i)[3] + "﹀" +
myPoints.get(i)[4] + "﹀" +
myPoints.get(i)[5].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[6].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[7].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[8].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[9].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[10].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[11].replaceAll("﹀", "^") + "﹀" +
myPoints.get(i)[12].replaceAll("﹀", "^") + "\n";
}
}
// поток
final String finalTxt = txt;
Thread thread = new Thread() {
@Override
public void run() {
//Сохраняем переменную в файл
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file_name);
byte[] buffer = finalTxt.getBytes();
fos.write(buffer, 0, buffer.length);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fos != null)
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//конец потока
}
};
thread.start();
}
Время у вас уходит на создание огромного количества строк в цикле, это классическая ошибка, о которой много где написано.
Плюс к этому непонятно, зачем сперва делать делать строку, а потом писать её, если можно сразу писать в файл? Таким образом вам не нужно держать эту большую строку в памяти:
private static final Set<Integer> REPLACE_INDEXES = new HashSet<>(Arrays.asList(1,5,6,7,8,9,10,11,12));
private final int STRING_ARRAY_SIZE = 13;
public void mySavePoints(final String fileName) throws IOException {
FileWriter fw = new FileWriter(fileName);
for (int i = 0; i < myPoints.size(); i++) {
for(int j = 0; j < STRING_ARRAY_SIZE; j++){
if(REPLACE_INDEXES.contains(j)){
fw.write(myPoints.get(i)[j].replaceAll("﹀", "^"));
} else {
fw.write(myPoints.get(i)[j]);
}
fw.write('﹀');
}
fw.write("\n");
}
fw.close();
}
Дело в том, что объекты класса String
- неизменяемы, то есть вы добавляя что-то к стринге, вы создаёте новый объект, сохранив старый. У вас - чистая утечка памяти. Используйте класс StringBuilder
- это аналог String
, только изменяемый.
Итак:
Создайте объект класса StringBuilder:
StringBuilder out = new StringBuilder(""); //Строка для записи массива строк
В эту строку запишите весь массив строк.
for(int i = 0; i<myPoints.size(); i++){
out.append(myPoints.get(i));
}
Полученную строку запишите в txt.
По моему авторитетному мнению, должно получаться 0.5-5 секунд на всё.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Пытался прикрутить к простейшему проекту tiles из примера https://o7planningorg/ru/11683/spring-boot-apache-tiles-jsp-tutorial все вроде делал по писанному, за исключением...
Делаю практическое задание для универа на Android Studio, мне нужно делать get запросы к странице, чтобы получать данные с БД, но ни один из найденных...
я начинающий программист, изучаю Java и хочу изучать разработку под AndroidПроблема в том, что я не могу найти правильный подход к изучению, и меня...