Java szukanie wartosci w kolumnie

0

Dzień dobry,

Mam pewien problem. Piszę program w javie, który pobiera plik .csv i zapisuje go do tablicy dwuwymiarowej. Teraz biorę sobie trzecią kolumnę z tej tabeli, która wygląda tak:

24678
24678
24678
24678
24678
24678
24677
24677
24677
24677
24677
24678
24678
24678
24678
24678
24678
24678
24678
24678
24678
24677
24677
24677
24677
24677
24677
24677
24677
24677
24677
24677
24677

Teraz chcę ją przeszukiwać aż trafię na zmianę wartości i zapisywać tylko tylko te wartości ostatnie przed zmianą. Czyli w tym wypadku wiersz 6, wiersz 11, wiersz 21. Kompletnie nie wiem jak to zrobić. Próbowałem coś w stylu:
for(int i = 0; i < table[3].length; i++)
if (table[1][3] != table[i][3]) {
system.out.println(table[i][3]);
} else {
system.out.println(table[1][3]);

Wiem, że to jest kompletnie źle ale nie mam na to pomysłu jak pobierać ostatnią wartość przed zmianą. Czy stworzyć dwie zmienne i porównywać po kolei czy jak...

Będę wdzięczny za każdą próbę pomocy. Z góry serdecznie dziękuję.

0
for(int i =0; i < table.length; i++)
{
      if(table[i][3] != table[i+1][3])
         System.out.println(table[i][3]);
}

Zadziala jeśli tablica ma przynajmniej rozmiar 2.

Edit:
Poprawione zgodnie z zaleceniami ;)

for(int i =1; i < table.length; i++)
{
      if(table[i-1][3]!= table[i][3])
         System.out.println(table[i-1][3]);
}
0

a żeby temu zaradzić co w komentarzu:
for powinien być rozpoczęty od i=1
i+1 zmienić na i;
i zmienić na i-1;
i wtedy będzie to jakoś działać - żeby było zabawniej dla dowolnego rozmiaru tablicy
tak więc 2 bugi za jedną zmianą - tablica nie musi mieć minimum rozmiaru 2, i nie spsuje się brzydko pod koniec.

0

Dziękuję Wam bardzo za odpowiedzi ale Wasze rozwiązanie pokaże mi wszystkie nie pasujące wiersze do pierwszego, a zależy mi na tych, które są ostatnie przed zmianą wartości.

0

Nie

0

Wcześniej za bardzo wziąłem pod uwagę Twój kod: table.length zamiast table[3].length. Jeśli masz tablice table[i][2] to w Twoim wypadku table[3].length zwracałoby wartość 2 zamiast liczbę rekordów czyli i.

0

Co by nie było, problem uważam za rozwiązany ;]

0

Zastosowując waszą pętlę wyrzuca mi takie wiersze:

24678
24678
24678
24678
24678
24678
24677
24677
24677
24677
24677
24678

Potrzebuję tylko trzech wierszy czyli
24678
24677
24678

To znaczy ostatnich wierszy przed zmianą wartości wiersza.

0

edit: Niestety nie do końca rozwiązany ... :(

0

To coś jest nie tak, ale nie z warunkiem pętli tylko z danymi.
Te dane przykładowe na pewno drukowałeś adresując tablice [i][3]?? (System.out.println([i][3])?

0

Tablica jest typu int czy string?

Jelsi String to if(!table[i-1][3].equals(table[i][3])) (...)

0

Tablica jest typu String[][]. [i] - liczba wierszy, [j] - liczba kolumn.

0

Tak, żeby pokazać kolumnę trzecią (no czy tam drugą, bez znaczenia) z tabeli puszczałem w pętli System.out.println(line[i][3]);

0

W takim razie pierwszym blędem jest sprawdzenie != . Przy Stringach musisz korzystac z metody equals - tak jak napisałem w poprzednim poście (nie zapomnij o "!" w tym ifie).

0

Dobra, działa dzięki Wam. Dziękuję serdecznie za pomoc.

0

no mówiłem:, że problem rozwiązany a dalsze zgrzyty leżą po stronie danych ( w tym przypadku typu) :0

0

Znów potrzebuję Waszej pomocy. Piszę dalej ten program, chcę teraz zapisać wyodrębnione przeze mnie wiersze do nowego pliku csv. Muszę sklejać te dane tak jak widać ale to nieważne. Robie to tak:

for (int i = 1; i < line.length; i++)
{
if(!line[i-1][2].equals(line[i][2]))
System.out.println(line[i][0]+';'+line[i-1][1]+';'+line[i-1][2]+';'+line[i-1][8]+';'+line[i-1][4]+';'+line[i][1]+';'+line[i][2]+';'+line[i][8]+';'+line[i][4]+';'+line[i][6]+';'+line[i][7]+';'+line[i][5]+';'+line[i][9]+';'+line[i][10]+';'+line[i][11]+';'+line[i][12]);

            String outputFile = "users.csv";
            boolean alreadyExists = new File(outputFile).exists();
            try {

CsvWriter nowy = new CsvWriter(new FileWriter(outputFile, true), ';');

nowy.write(line[i][0]);
nowy.write(line[i-1][1]);
nowy.write(line[i-1][2]);
nowy.write(line[i-1][8]);
nowy.write(line[i-1][4]);
nowy.write(line[i][1]);
nowy.write(line[i][2]);
nowy.write(line[i][8]);
nowy.write(line[i][4]);
nowy.write(line[i][6]);
nowy.write(line[i][7]);
nowy.write(line[i][5]);
nowy.write(line[i][9]);
nowy.write(line[i][10]);
nowy.write(line[i][11]);
nowy.write(line[i][12]);
nowy.endRecord();

     nowy.close(); 
  } catch (IOException e) {
  }

}

Po odpaleniu tego kodu z danych wyciągniętych wcześniej powinno mi wyrzucić 3 wiersze złożone tak jak wyżej z takich komórek. Wyrzuca mi jakieś dziwne wyniki, wpierw całe te trzy wiersze w jednym a po nim całą wcześniejszą tabelę i dokleja jeszcze dużo nowych wierszy. Nie wiem co robię źle. Powinienem gdzieś jeszcze dodać albo zmodyfikować, że jak nie ma znaku ; to przejdz do następnego wiersza... ? Będę bardzo wdzięczny za każdą pomoc.

0

po 1)
Jestem w robocie i nie chce mi się analizować tego sklejania :]
po 2)
Zanim zapiszesz do pliku, wywal to co robisz na konsole, żeby mieć kontrole i na bieżąco poprawiać błędy konkatenacji (sklejania stringów)
po 3) - w sumie to powinno być jako 2
Twój magicznie sklejony string wstaw pod nową zmienną np String line; i pracuj dopiero na takim czymś. Teraz robisz (tak jakby) 2 razy jedną robotę. Sklejasz żeby sobie coś na konsoli wyświetlić, a później sklejasz na pliku.

0

Z tego co widze ifem sprawdzasz tylko wypisywanie System.out.println(...), a write jest wykonywany w każdej iteracji pętli bo nie objąłeś go blokiem { } od ifa.
Na razie tu widze nieporozumienie ; p

No i wykonywanie w każdej interacji:

String outputFile = "users.csv";
boolean alreadyExists = new File(outputFile).exists();
                try {
CsvWriter nowy = new CsvWriter(new FileWriter(outputFile, true), ';');

też mija się z celem raczej, nie jestem do końca pewien co chcesz tu osiągnąć

Wyrzuć przed pętle takie rzeczy

0

Ok, poszło, nie objąłem ifem odpowiedniego fragmentu. Dzięki serdecznie drugi raz. Jeszcze jedno pytanie (mam nadzieję, że ostatnie). Chcę żeby w kolumnie o takkiej zawartości:
24678
24678
24678
24678
24678
24678
24677
24677
24677
24677
24677
24678
24678
24678
24678
24678
24678
24678
24678
24678
24678
24677
24677
24677
24677
24677

Obok liczb w nawiasie pojawiała się liczba zapisana hex czyli wiesze wyglądałyby tak: 24677 (6065) itd.
Próbowałem coś z Integer.toHexString(i) ) ale jak zamiast i mówię mu, żeby w pętli przeszedł całą kolumnę czyli:
System.out.println(line[i][3]+''+Integer.toHexString(line[i][3]);
to wywala błąd. Można to jakoś inaczej zrobić ?

0

nie wiem jaki błąd to po pierwsze ;P fajnie jakbyś wkleił

po drugie jeśli to co napisales jest przekopiowane z kodu to +"+ ==> +" "+. Dwa cudzysłowy

po trzecie nawias przed średnikiem ;)

po czwarte... argumentem tej metody jest int a z tego co pamiętam masz String w tej tabeli --> najpierw parsuj String na int, pozniej uzyj metody toHex
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Integer.html#parseInt%28java.lang.String%29

0
 
import com.csvreader.CsvWriter;
import java.io.*;
 import java.net.URL;
 import java.util.Scanner;
 import javax.swing.*;
 import javax.swing.table.DefaultTableCellRenderer;
 import javax.swing.table.DefaultTableModel;
import javax.swing.JButton;  
import javax.swing.JFrame;  
import java.awt.BorderLayout;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.awt.FileDialog;
import java.awt.Frame;

 public final class CSVTable extends JFrame {
    JTable table;
    DefaultTableModel model;
    JButton closeButton, webButton, ConvertButton;

  public CSVTable(String title, String source) throws NumberFormatException {

    InputStream is;
    try {
        if(source.indexOf("http")==0) {
            URL facultyURL = new URL(source);
            is = facultyURL.openStream();
        }
        else { //local file?
            File f = new File(source);
            is = new FileInputStream(f);
        }
        insertData(is);
        //table.getColumnModel().getColumn(0).setCellRenderer(new CustomCellRenderer());
    }
    catch(IOException ioe) {
        JOptionPane.showMessageDialog(this, ioe, "Error reading data", JOptionPane.ERROR_MESSAGE);
    }
}

void insertData(InputStream is) throws FileNotFoundException, IOException, NumberFormatException {
    Scanner scan = new Scanner(is);
           String n = scan.toString();
    String[][] line = new String[n.length()][13];
   String[] array = null;
   String line1;
        int row =0;
        int col =0; 
   while (scan.hasNextLine()) {
        line1 = scan.nextLine();
        StringTokenizer st = new StringTokenizer(line1, ";", false);
        while (st.hasMoreTokens()) {
            line[row][col] = st.nextToken();
        col++;
        }
        col = 0;
        row++;
   }
           System.out.println("\n                \n");
           for (int i = 1; i < line.length; i++)
           {
               
               if(!line[i-1][2].equals(line[i][2])) {
                   int b = Integer.parseInt(line[i-1][1]);
                   int c = Integer.parseInt(line[i-1][2]);
                   int d = Integer.parseInt(line[i][1]);
                   int f = Integer.parseInt(line[i][2]);
                   System.out.println(line[i][0]+';'+line[i-1][1]+""+Integer.toHexString(b)+';'+line[i-1][2]+""+Integer.toHexString(c)+';'+line[i-1][8]+';'+line[i-1][4]+';'+line[i][1]+""+Integer.toHexString(d)+';'+line[i][2]+""+Integer.toHexString(f)+';'+line[i][8]+';'+line[i][4]+';'+line[i][6]+';'+line[i][7]+';'+line[i][5]+';'+line[i][9]+';'+line[i][10]+';'+line[i][11]+';'+line[i][12]);
                   
                           String outputFile = "C:\\Documents and Settings\\Vieckov\\Pulpit\\Wynik\\X004402141929004_1334824654152.csv";
                boolean alreadyExists = new File(outputFile).exists();
                try {
CsvWriter nowy = new CsvWriter(new FileWriter(outputFile, true), ';');

nowy.write(line[i][0].substring(0, 19));
nowy.write(line[i-1][1]+" ("+Integer.toHexString(b)+")");
nowy.write(line[i-1][2]+" ("+Integer.toHexString(c)+")");
nowy.write(line[i-1][8]);
nowy.write(line[i-1][4]);
nowy.write(line[i][1]+" ("+Integer.toHexString(d)+")");
nowy.write(line[i][2]+" ("+Integer.toHexString(f)+")");
nowy.write(line[i][8]);
nowy.write(line[i][4]);
nowy.write(line[i][6]);
nowy.write(line[i][7]);
nowy.write(line[i][5]);
nowy.write(line[i][9]);
nowy.write(line[i][10]);
nowy.write(line[i][11]);
nowy.write(line[i][12]);
nowy.endRecord();
nowy.close(); 
                } catch (        NumberFormatException | IOException e)
                {
      } 
}
}

model.addColumn(line);
model.addRow(line);
    table.setModel(model);
}
public static void main(String args[]) throws IOException, NumberFormatException {

    CSVTable frame = new CSVTable("input","X004402141929004_1334824654152.csv");
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

To powyżej to jest mój cały śmieszny rozwalony brzydki kod, w którym jest okropny syf, jakimś cudem działa. Teraz chciałbym się pozbyć tego nie udanego przeklejonego skądś tam gui i zrobić tak, żeby czytał mi po prostu plik jako parametr w terminalu a wywalał ten zpreparowany do jakiegoś tam folderu (wynik\). Czytałem coś o system.in ale nie wiem jak się pozbyć tego gui i zamienić to po prostu na system.in bo jest to związane z pobieraniem tego pliku i zamianą na tablicę dwuwymiarową jak z resztą sami widzicie. Pomożecie... ?

0

I jeszcze jedno. Tworzy mi plik, który chciałem ale jednocześnie wywala taki błąd:
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.parseInt(Integer.java:527)
at CSVTable.insertData(CSVTable.java:118)
at CSVTable.<init>(CSVTable.java:46)
at CSVTable.main(CSVTable.java:164)
Java Result: 1

Więc dodałem wszędzie gdzie się tylko dało wyjątek NumberFormatException i to nic nie dało. Błąd zaczął się wtedy gdy z tablicy line[147][33] zmieniłem na:
String n = scan.toString();
String[][] line = new String[n.length()][13]; bo chcialem pobierrać pliki o różnej ilości wierszy.

Nie mam juz pomysłu gdzie może być błąd :(

0

Czytaj czytaj czytaj to co Ci ex wywala. Przecie jest wyraźnie, że null nie jest liczbą. Proste - zasysasz z pliku nula ( nie nie musi to być tekst:null w pliku)
btw co rozumiesz po przez -

Więc dodałem wszędzie gdzie się tylko dało wyjątek NumberFormatException
bo to bardzo mnie interesuje :D
Tam gdzie błąd Ci wywala czyli w linii 164 implementacji klasy CSVTable w metodzie 164 ( tak tak uczymy się czytać dump stosu) wstawić musisz zabezpieczenie przed nulem (czyli sprawdzasz czy null czy cos tam czy coś tam i jak można z tego zrobić liczbę to dopiero ją rób);

0

No w paru miejscach kodu pokazuje mi błąd więc dodałem wszędzie NumberFormatException ;) A z Twojego tłumaczenia nie wiele zrozumiałem, żeby nie powiedzieć nic.

0

Nadal nie rozumiem w jaki sposób dodałeś (co lepiej gdzie i do czego) NumberFormatException ;]

edit:

No jak nie rozumiesz;]
Patrz dam Ci 2 przykłady w jakich dostaniesz ten wyjątek:
Integer.parseInt(null);
Float.parseFloat("liczba_zmiennoprzecinkowa_akurat")
U Ciebie występuje ta pierwsza sytuacja ;]

jak mi pokażesz co masz w

linii 164 implementacji klasy CSVTable
to Ci powiem może gdzie tego nula dostajesz ;]

PPS:
Dump stosu, a bardziej precyzyjne stack trace - lista adresów(w wysokopoziomowym - miejsc w kodzie) w których następowały wywołania metod (a tym samym odkładały się adresu powrotów do nich na stosie).
Jak dostajesz jakiś exception to zwykle drukuje Ci własnie takie drzewko jak pokazałeś powyżej (można je też samemu drukować np wykorzystując metodę Exception#printStackTrace)
Tam widzisz DOKŁADNIE w której linii kodu pojawił się wyjątek (w twoim przypadku jest to 164 linia)
A tak naprawdę to winowajca leży

at CSVTable.insertData(CSVTable.java:118)
at CSVTable.<init>(CSVTable.java:46)
at CSVTable.main(CSVTable.java:164)

na 118 linii

0

if (line[i][1] == null) {

                   throw new NumberFormatException("null");}
               int d = Integer.parseInt(line[i][1]);

Dodałem coś takiego. Pewnie jest kompletnie źle. Ale na prawde nie wiem jak to zrobic.

0

Dobra, poradziłem sobie. Jeszcze podpowiedźcie, jak mam to zrobić żeby usunąć to całe CSV table i żeby po prostu jak parametr podawać nazwe pliku i zeby mi tworzył nowy o tej samej nazwie. Nie wiem czy to sie w ogóle da zrobić..

0

Ogólnie z tym wyjątkiem sobie poradziłem ale nie wiem jak zrobić to z parametrem bo to pewnie jest troche roboty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1