Początki z javą parsowanie pliku "obiektowo"

Początki z javą parsowanie pliku "obiektowo"
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

Hej.
Stworzyłam sobie prostą klasę "Studenci" i w klasie do testów w main()

Kopiuj
ArrayList<Studenci> studenci = new ArrayList<Studenci>();

. Chciałabym teraz wczytać sobie Imię,Nazwisko każdego studenta z pliku i wstawić do odpowiedniego obiektu Student w ArrayList. Jak prawidłowo obiektowo powinnam to zrobić? Stworzyć klasę np. ReadFile i tam metody np. getLineCounter(); getImie(int id); getNazwisko(int id); ? I potem w main() pętlę typu for(i=0;i<readFile.getLineCounter();i++)

Kopiuj
 i po kolei jechać sobie ustawiać? Czy to jest prawidłowe podejście? Tylko wtedy będę musiała w klasie ReadFile utworzyć oddzielne ArrayList<String> na przechowywanie Nazwisk, oddzielne na Imiona tak? Trochę wydajnościowo to kiepsko wygląda chyba :?
Pozdrawiam

PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
edytowany 1x, ostatnio: karolinaa
pats
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 11 lat
  • Postów:12
1

Ja zawsze robiłem w ten sposób:

Kopiuj
import java.util.*;

class Student {
    private String imie;
    private String nazwisko;

    public Student(String i, String n) {
        imie = i;
        nazwisko = n;
    }

    public String toString() {
        return imie + " " + nazwisko;
    }
}


public class Prog {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<Student> studenci = new ArrayList<Student>();

        while (sc.hasNext()) {
            String imie = sc.next();
            String nazwisko = sc.next();
            studenci.add(new Student(imie, nazwisko));
        }

        for (Student s: studenci) {
            System.out.println(s);
        }
    }
}

Później wystarczy wywołać java Prog < studenci.txt zakładając, że plik jest poprawny. Można też zmienić wczytywanie tj. zamienić System.in na np. new File("studenci.txt").

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@karolinaa to zależy jak te dane przechowujesz. No jeśli to coś na wzór "jedna linia - jeden obiekt" to możesz zrobić konstruktor Student który potrafi zrobić studenta na podstawie takiej linii. Jeśli wymaga ona jakichś cudów na kiju, regexpów etc to mozesz zrobić też jakiegoś helpera który w tej konstrukcji będzie pomagał.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

@Shalom helper... czyli? hmm... jeszcze mam problemy z tą obiektowością mianowicie: co w przypadku jeśli w przyszłości zmienię sobie format pliku? Załóżmy w pierwszej linijce dodam informację o grupie tych studentów, np plik:

Kopiuj
[GRUPA G435C]
[Paweł==Trybson]
[Ania==Duża]
[Wojtek==Jakistam]

Nie chciałabym wtedy rozgrzebywać całego programu.
Czy taka klasa to jest dobry pomysł? zwłaszcza te ArrayList w tej klasie mnie martwią ;/?

Kopiuj
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileParse {
	private final static Charset ENCODING = StandardCharsets.UTF_8;
	private final Path FilePath;
	private ArrayList<String> names = new ArrayList<String>();
	private ArrayList<String> surnames = new ArrayList<String>();
	private int recordsCounter = 0;


	public FileParse(String FilePath) {
		this.FilePath = Paths.get(FilePath);
	}

	public String getName(int id) {
		return names.get(id);
	}

	public String getSurname(int id) {
		return surnames.get(id);
	}

	public int getRecordCounter() {
		return recordsCounter;
	}

	public final void parse() throws IOException {
		try {
			Scanner scanner = new Scanner(FilePath,ENCODING.name());
			//w pierwszej linijce pojawiła się informacja o grupie, więc dodaję
			processGroupInfo(scanner.nextLine());
			while (scanner.hasNextLine()){
				processRecord(scanner.nextLine());
			}
		} catch(IOException ex) { System.out.println("do ogarnięcia"); }
	}

	protected void processRecord(String Line) {
		Pattern recordPattern = Pattern.compile("\\[(.*)==(.*)\\]");
		Matcher recordMatcher = recordPattern.matcher(Line);
		if(!recordMatcher.find())
			return;
		names.add(recordsCounter, recordMatcher.group(1));
		surnames.add(recordsCounter, recordMatcher.group(2));
		recordsCounter++;
	}

	/* format pliku zmienił się w pierwszej linii dodam informację
	odnośnie nazwy grupy tych studentów np. [M101] dodaję, więc:
	 */

	private String groupInfo;
	public String getGroupInfo() {
		return groupInfo;
	}

	protected void processGroupInfo(String Line) {
		Pattern groupPattern = Pattern.compile("\\[(.*)\\]");
		Matcher groupMatcher = groupPattern.matcher(Line);
		if(!groupMatcher.find())
			return;
		groupInfo = groupMatcher.group(1);
	}

}

potem przy parsowaniu używam np tylko:

Kopiuj
FileParse test = new FileParse("test.txt");
test.parse();
System.out.println(test.getGroupInfo());
for(i=0;i<test.getRecordCounter();i++)
      records.add(i,new Student(test.getSurname(i),test.getName(i)));

PS
proszę nie zwracać uwagi na głupie nazwy zmiennych czy brak obsługi wyjątków jestem początkująca i chodzi tylko oto jak podejść do takiego zagadnienia prawidłowo.
a i obiekt Student do którego wczytuje Imię i Nazwisko z pliku ma jeszcze inne pola, np. Numer Indeksu - ale to pobieram już z innego miejsca.


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Shalom
Srsly, ludzie z warsaw shore? Miałem o Tobie lepsze zdanie :P
KA
o jej to fajny rozrywkowy program. oglądam dla beki. niedziela 23:00 - obowiązkowo mtv :)
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Moim zdaniem takie rozwiązanie jest mega słabe. To już lepiej by było gdyby ten twój parser potrafił jednak sam tworzyć tych studentów, bo w zasadzie to jest taki "transformer" który przetwarza jedną reprezentację obiektów (tekstową w pliku) na inną.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
0

Najlepiej w tym celu skorzystać z normalnej bazy danych albo mechamizmu serializacji (ObjectInputStream i ObjectOutputStream). Ewentualnie bibliotekę Kryo, która ponoć ma znacznie wyższą wydajność.

KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

@Shalom a mogłabym od razu w tym "parserze" tworzyć ArrayList obiektów klasy Student? i potem zwrócić po prostu tak żebym mogła na tym operować w main()?
@niezalogowany - na razie to chciałam nauczyć się podstaw :)


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
edytowany 1x, ostatnio: karolinaa
pats
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 11 lat
  • Postów:12
1

Moim zdaniem, lepiej zrobić osobną klasę, która zawiera dane o studencie, tak jak w moim poprzednim poście. Ta klasa powinna być niezależna od rodzaju wczytywania, bo mogą być różne metody (z pliku, z bazy danych). Helper w tym przypadku jest pomocny i oznacza, aby zrobić dodatkową klasę która wczytuje dane z pliku i zwraca listę studentów. Gdy później będziesz potrzebowała obsłużyć inny format pliku, wystarczy napisać kolejny helper.

KA
łał dzięki! toteż tak zrobię, bo myślałam właśnie podobnie.
KA
KA
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:1683
0

heh ,dobra mam jeszcze dwa pytania (dopiero teraz mam znowu czas na Javę);

  1. Mój projekt składa się z kilku osobnych plików (*.java). W osobnym pliku mam klasę Student, Czy klasę "StudentsFileHelper" tak samo mogę umieścić w osobnym pliku i zrobić ją public?
  2. Czy do "parsowania" z pliku informacji na temat tego pliku (1 wiersz np. Autor, Data spisu), powinnam stworzyć osobną klasę? Np. InfoFileHelper?
Kopiuj
[Jan Nowak - 15.01.2014]
[Paweł==Trybson]
[Ania==Duża]
[Wojtek==Jakistam]

Przejrzałam przed chwilą sobie pobieżnie Single Responsibility Principle, Low Coupling stąd http://www.e-point.pl/_fileserver/item/1500355 i chcę się po prostu upewnić czy prawidłowo obiektowo do tego podchodzę. tak żeby sprzyjało to przyszłej skalowalności aplikacji.
Pozdrawiam i dzieki


PROGRAMY NA ZAMÓWIENIE, ZALICZENIA STUDENCKIE, KONFIGURACJA SERWERÓW, SYSTEMÓW I BAZ DANYCH, STRONY INTERNETOWE, POMOC W PROGRAMOWANIU, POPRAWIENIE I OPTYMALIZACJA APLIKACJI
JAVA, C++, LINUX, WWW, SQL, PYTHON
POSIADAM KOMERCYJNE DOŚWIADCZENIE
TANIO, SZYBKO I PORZĄDNIE
Z KOMENTARZAMI OBJAŚNIAJĄCYMI KOD
PISZ NA PRYWATNĄ WIADOMOŚĆ
CENY JUŻ OD 49,99ZŁ ZA PROGRAM
ZAJMIJ SIĘ TYM CO CIĘ NAPRAWDĘ INTERESUJE!
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)