Przekazywanie wektora przez wartość

Odpowiedz Nowy wątek
2011-07-25 00:43
0

Mam wektor z danymi bazowymi. (Wiem, że wektor jest przestarzały ale z DefaultTableModel (DTM) mozna pobrac dane tylko w postaci wektora). Wektor jest przekazywany w konstruktorze do kilku innych obiektów DTM. Oczywiście w ten sposób tworzone są nowe kopie, jednak operują na tej samej pamięci. Modyfikując komórkę w jednej tabeli modyfikowana jest ona we wszystkich oraz w danych bazowych (które nie powinny byc modyfikowane).

Kombinowalem juz oznaczyc wektor z danymi jako final, jednak szybko zorientowalem sie ze nie bedzie mozna zmienic jedynie wskazywanego obiektu. Probowalem z funkcja clone(), oraz przekazywaniem wektora w postaci tablicy (gdzies tak kiedys wyczytalem), no ale ciagle problem wystepuje.

W skrócie: mam wektor danych który nie może być modyfikowany, a jest przekazywany do konstruktorów DTM. Jak to wykonać aby każdy DTM posiadał swój własny wektor danych a nie wskazywał na dane bazowe? W C++ byłoby to proste, a tutaj nie mogę się odnaleźć.

EDIT: Hmm w wektorze trzymam obiekty String, widze w dokumentacji iz nie implementuja one interfejsu Clonable, zatem jedynym wyjsciem jest serializacja i deserializacja wektora aby uzyskac jego kopie?

edytowany 1x, ostatnio: chybaprogramista, 2011-07-25 01:23

Pozostało 580 znaków

2011-07-25 07:57
bo
0

Nie wystarczy takie coś:

Vector<String> kopia=new Vector<String>(oryginał);

Pozostało 580 znaków

2011-07-25 10:30
0

Z pozoru wygląda to na bardzo ładne rozwiązanie, gdzie mamy dwa oddzielne wektory, dodając dane do kopii nie zmienia się oryginał.

Niestety tylko z pozoru ponieważ, gdyby w wektorze oryginal zamiescic String "oryginal", a nastepnie wykonac kopie tegoż wektora (w opisany przez Ciebie sposób) i dodać go do DTM jako dane to będziemy w DTM operowali na tej samej referencji Stringu, mimo że referencje wektorów są inne. Zmieniając dane w JTable, zmienia się zatem wektor oryginalny oraz kopię.

Pozostało 580 znaków

2011-07-25 10:39
bo
0

Sprawdziłeś?

import java.util.*;
 
public class Wektory
{
    public static void main(String[] args)
    {
        Vector<String> first=new Vector<String>();
        first.add("jasna");
        first.add("dupa");
        Vector<String> second=new Vector<String>(first);
        second.set(0,"ciemna");
        System.out.println(first.get(0)); //jasna
        System.out.println(second.get(0)); //ciemna
    }
}

Pozostało 580 znaków

2011-07-25 12:37
0

Zauważ, że Ty 'podmieniasz' String w wektorze na 0 pozycji - po set() jest tam inna referencja, jednak nie 'zmieniasz' Stringu "jasna".

W JTable w komórce masz referencje stringu "jasna", zmieniajac go w komórce np. na "jasna_zmiana" w obu wektorach zostanie podmieniony String.

Pozostało 580 znaków

2011-07-25 12:37
0

Akurat ze stringami to jest zły przykład, bo są immutable. Problem pojawi się w momencie jak w tym wektorze są jakieś obiekty i zmieniamy np. tylko składową takiego obiektu.
Nie wiem czy jest jakaś metoda, którą to zrobisz w jednej linijce. Możesz w pętli pobierać elementy oryginalnego wektora, kopiować je i te kopie wrzucać do nowego wektora.

Vector<Jakas_klasa> first = new Vector<Jakas_klasa>();
first.add(new Jakas_klasa(1, 2, 3));
first.add(new Jakas_klasa(4, 5, 6));
 
Vector<Jakas_klasa> second = new Vector<Jakas_klasa>();
for(Jakas_klasa jk : first)
{
    second.add(new Jakas_klasa(jk)); //zakładając, że ta klasa ma odpowiedni konstruktor
}

Pozostało 580 znaków

2011-07-25 13:31
bo
0

Problem jest w tym, że Vector opisujący dane z modelu nie jest typu Vector<string> tylko Vector<Vector<string>>, a obiekty Vector<string> mogą się zmieniać.

    Vector<Vector<String>> kopia=new Vector<Vector<String>>();
    for(int i=0;i<oryginał.size();i++)
    {
        kopia.add(new Vector<String>(first.get(0)));
   }
Oczywiście ma być oryginał.get(i) (zamiast first.get(0);). - bogdans 2011-07-25 13:32

Pozostało 580 znaków

2011-07-25 13:35
0

Prosze oto kod w którym występuje problem.

Do konstruktora DTM została przekazana kopia wektora 'data' o nazwie 'kopia'.

Logicznie po zmianie stringu 'oryginal' w tabeli powinien zostać zmieniony tylko wektor kopia.

Przycisk 'check' drukuje w konsoli wektor 'data', ktory takze ulega zmianie.

Wszystko dlatego ponieważ oba wektory działają na tej samej referencji stringu 'oryginal'. Przynajmiej do takich wnioskow doszedlem.

import java.awt.BorderLayout;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
 
public class JavaApplication16 {
 
    public static void main(String[] args) {
 
        Vector<String> vect = new Vector<String>();
        vect.add("oryginal");
 
        final Vector data = new Vector();
        data.add(vect);
 
        Vector columnNames = new Vector();
        columnNames.add("name");
 
        JButton jButton = new JButton("check");
        jButton.addActionListener(new ActionListener() {
 
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(data);
            }
        });
 
        Vector kopia = new Vector(data);
 
        DefaultTableModel defaultTableModel = new DefaultTableModel(kopia, columnNames);
        JTable jTable = new JTable(defaultTableModel);
 
        JFrame frame = new JFrame();
 
        frame.add(jButton, BorderLayout.SOUTH);
        frame.add(jTable.getTableHeader(), BorderLayout.NORTH);
        frame.add(jTable, BorderLayout.CENTER);
 
        frame.setSize(200, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
Rzeczywiście masz racje, w pierwszym poście źle to troche ująłem, zapomniałem napisać że jest to w zasadzie wektor wektorów. Zatem jak rozwiazać problem najłatwiej? Zrobić kopię wewnętrznych wektorów i opakować je w inny wektor? Czy może są prostsze sposoby. - chybaprogramista 2011-07-25 13:39
Ach widzę, że odpowiedź już na mnie czeka w powyższym poście. I rozumiem, że to najłatwiejszy sposób? Serializacja i deserializacja także działa ale kopia będzie na pewno szybsza. - chybaprogramista 2011-07-25 13:41
Nie znam prostszego niż ten, który podałem w poprzednim poście. - bogdans 2011-07-25 13:43

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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