Форум

Data.BG Форуми: Четене на данни от текстов файл - Data.BG Форуми

Прехвърляне към съдържание

Страница 1 от 1
  • Вие не можете да започнете нова тема
  • Вие не може да отговаряте на тази тема

Четене на данни от текстов файл

#1
Потребителят е неактивен   Eyzebio 

  • Група: Потребители
  • Мнения: 49
  • Регистриран: 25-July 09
  • Репутация: 2
Здравейте! Финална нужда от помощ! Имам следната задача. Да прочета данни от един файл, да ги сплитна, използвайки regex израз и после да ги подам като аргументи на обекта от съответния клас. Дотук добре, нищо ниво и както го пишех, установих, че данните за типа на образованието могат да бъдат различни, тоест различните хора имат различни степени на образование. Как разбера колко обекта трябва да направя за всеки един от тях?
Същото се отнася и за осигуровките, които са внасяли, всеки човек е внасял различен брой осигуровки, съответно трябват различен брой обекти.

Така изглежда един запис от файла:
Пламен;Стойчев;Измирлиев;M;16.7.1980;206; България;София;Студентски;1016;Опълченска; 21;;;P;СОУ Уилям Гладстон;15.9.1986;15.6.1993;S;СОУ Уилям Гладстон;15.9.1993;30.6.1998;3.343;B;СОУ Уилям Гладстон;1.10.1999;1.6.2003;3.045
2016;11;1015.20;2016;10;605.93;2016;9;701.61;2016;7;981.86;2016; 4;1042.57;2016;3;919.87;2016;2;720.00;2015;12;969.75;2015;6;641. 16;2015;3;811.76;2015;2;757.07;2014;12;1321.31;2014;11;863.39; 2014;9;1539.51;2014;7;1159.62;2014;5;1295.59;2014;3;910.59;2014; 1;1033.80

Конструкторът на Education съдържа параметрите - степен на образование, училище, година на започване, година на завървашне , средна оценка.
Конструкторът на SocialInsuranceRecord съдържа параметрите година, месец и размер на вноската.

Ето това имам до момента, научено от курса:
package DataAccessLayer;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import DataObjects.address.Address;
import DataObjects.education.Education;
import DataObjects.insurance.SocialInsuranceRecord;
import DataObjects.personaldetails.Citizen;
import DataObjects.personaldetails.Gender;

public class GetDataFromFile {
private List<Citizen> citizents = new ArrayList<>();
private static final String FILE_PATH = "D:\\data.dat";
public Citizen parseCitizent(String nextLine) {
String[] split = nextLine.split("\\s*;");

Citizen citizen = new Citizen(split[0], split[1], split[2], Gender.valueOf(split[3]), LocalDate.parse(split[4]), Integer.parseInt(split[5]));
Address address = new Address(split[6], split[7], split[8], split[9], split[10], split[11], Integer.parseInt(split[11]), Integer.parseInt(split[12]));
citizen.setAddress(address);
List<Education> educations = new ArrayList<>();
// to do...
citizen.set_educations(educations);
List<SocialInsuranceRecord> socilInsuranceRecords = new ArrayList<>();
// to do...
citizen.set_socialInsuranceRecords(socilInsuranceRecords);
return citizen;
}
}
0

#2
Потребителят е неактивен   brigadier 

  • Група: Потребители
  • Мнения: 1101
  • Регистриран: 25-December 05
  • Репутация: 247
В единия списък добавяш 3 реда, а във втория - 18 , ако правилно ги преброих:

1. educations.add(new Education(които парчета са наред));
2.
3.

1. sociаInsuranceRecords.add(new SocialInsuranceRecord(които парчета са наред));
2.
.....
18.
0

#3
Потребителят е неактивен   Eyzebio 

  • Група: Потребители
  • Мнения: 49
  • Регистриран: 25-July 09
  • Репутация: 2
Проблемът е, че всеки човек е завършил различна степен на образование и е платил различен брой осигуровки. В този случай не знам как да направя проверка колко образователни степени има и за колко месеца назад си е платил осигуровките. Единственто, което им хрумва е, че единият клас има три параметъра, а другият четири.

Йордан;Симеонов;Мавродиев;M;9.5.1954;171; България;София;Витоша;1017;Петър Васков;2;;;P;СОУ Уилям Гладстон;15.9.1960;15.6.1967;S;СОУ Уилям Гладстон;15.9.1967;30.6.1972;5.182
2016;11;1362.95;2016;10;1015.96;2016;9;957.01;2016;8;1531.26; 2016;5;848.11;2016;3;991.68;2016;2;771.66;2015;12;1477.28;2015; 10;677.05;2015;7;1414.83;2015;4;1513.03;2015;1;943.38;2014;8;833. 17;2014;2;707.30;2014;1;780.57;2013;12;1202.31

Виолета;Константинова;Орлова;F;23.8. 1982;148;България;София;Изгрев;1008;Цар Борис III;123;5;26;P;СОУ Уилям Гладстон;15.9.1988;15.6.1995;S;СОУ Уилям Гладстон;15.9.1995;30.6.2000;4.069
2016;11;1587.70;2016;8;1524.04;2016;6;1273.10;2016;4;1129.08; 2016;2;1469.79;2015;12;927.91;2015;10;1116.83;2015;6;1143.05;2015; 4;1348.82;2015;1;612.03;2014;12;1155.69;2014;8;1407.81;2014;1; 707.37;2013;12;1414.82


Идеята ми след това е запиша всички прочетени данни в списък Citizen, а оттам вече да вкарам създадената база от данни.
public List<Citizen> getCitizens() {
List<Citizen> list = new ArrayList<>();
try {
Scanner scanner = new Scanner(new String(Files.readAllBytes(Paths.get(FILE_PATH))));
while(scanner.hasNext()) {
Citizen citizen = parseCitizent(scanner.nextLine());
list.add(citizen);
}

}catch(Exception ex) {
ex.printStackTrace();
}
return list;
}

Мнението беше редактирано от Eyzebio: 30.11.16 - 12:53

0

#4
Потребителят е неактивен   brigadier 

  • Група: Потребители
  • Мнения: 1101
  • Регистриран: 25-December 05
  • Репутация: 247
Параметрите тук не ти помагат. Ако всеки Citizen няма точно фиксирани 3 + 18 записа за обучение и вноски, а варират, може да вкараш Pattern

1. За обучение - S;СОУ Уилям Гладстон;15.9.1967;30.6.1972;5.182 , обърнато в regex
2. За вноски - 2016;11;1362.95; , пак обърнато в regex

След това условие при попълване на списъка

boolean isEducation = Matcher.matches(pattern);
int counter = текущия номер на парчето;
(while isEducation){
educations.add(new Education(split[counter] , split[counter+1], split[counter+2], split[counter+3], split[counter+4]);
counter +=5;
isEducation = Matcher.matches(pattern); //тук броячът се мести след проверените 5 парчета
}

На същия принцип за вноските.

Общата конструкция е : правиш обект Citizen. Две от променливите в него са списъци с обекти. Правиш двата списъка и ги вкарваш във Citizen със set метода. Най - накрая можеш да направиш и списък със Citizens

Pattern - https://docs.oracle....ex/Pattern.html
Matcher - https://docs.oracle....ex/Matcher.html

Мнението беше редактирано от brigadier: 30.11.16 - 16:27

0

#5
Потребителят е неактивен   Eyzebio 

  • Група: Потребители
  • Мнения: 49
  • Регистриран: 25-July 09
  • Репутация: 2
Тоест ако съм те разбрал правилно, правя си още един обект от Scanner, чета отново данните през него от файла и ги филтрирам с подходящия regex израз за образованите и вноските :)?
Освен това при изпълнението на този ред String[] split = nextLine.split("\\s*;"); премахвам знака ;.

Мнението беше редактирано от Eyzebio: 30.11.16 - 19:45

0

#6
Потребителят е неактивен   brigadier 

  • Група: Потребители
  • Мнения: 1101
  • Регистриран: 25-December 05
  • Репутация: 247
Много отдавна не съм ползвал Scanner , но принципът е : конструираш си 2 Patterns

1. За education = 1 Character + произволно дълъг String + дата + дата + Double
2. За socialInsurance = 4 знака цифри + 1 или 2 знака цифри + Double

Като направиш обект Citizen, чекваш дали следващите 5 парчета съответстват на education Pattern. Ако да - добавяш нов Education обект в списъка, докато свършат. Ако не - чекваш вноските , и ако следващите 3 парчета пасват на втория Pattern, добавяш нов SocialInsuranceRecord в другия списък. След като завърши всеки списък, го вкарваш със set вътре в Citizen , а накрая завършения Citizen влиза в общия списък Citizens.

Не помня вече и как стоеше въпросът с consum - ването на скенера, понеже там чекването е само за next() и не можеш да се връщаш. Аз бих вкарал целия скенер в един общ String и вече вътре в него можеш да си проверяваш както си искаш пo substring.

EDIT Всъщност по - добре е да вкараш скенера директно в String Array и да караш по индекса. Първите 6 = new Citizen. Следващите 5 : ако първия пасва на 1 Character && втория на произволно дълъг String && итн -> добавяш нов Education обект в списъка , ако не : ако първия пасва на 4 знака цифри && итн до третия -> добавяш нов SocialInsuranceRecord в другия списък. Само трябва да преоформяш където трябва типовете от String за да паснат на конструктора.

Мнението беше редактирано от brigadier: 30.11.16 - 21:44

0

#7
Потребителят е неактивен   Eyzebio 

  • Група: Потребители
  • Мнения: 49
  • Регистриран: 25-July 09
  • Репутация: 2
Добре, ще пиша утре вечер докъде съм стигнал. Благоаря за отделенето време :)!
0

Споделете тази тема чрез:


Страница 1 от 1
  • Вие не можете да започнете нова тема
  • Вие не може да отговаряте на тази тема

1 потребители четат тази тема
0 регистрирани потребители, 1 гости и 0 анонимни потребители


Data.BG e форум за дискусии. Data.BG не носи отговорност за съдържанието и достоверността на публикуваните в дискусиите материали.

Никаква част от съдържанието на тази страница не може да бъде репродуцирана, записвана или предавана под каквато и да е форма или по какъвто и да е повод без писменото съгласие на Data.BG.

Close  Member Login