Копировать ObservableList java

#java #javafx #javafx-2 #observablelist

#java #javafx #javafx-2 #observablelist

Вопрос:

У меня есть a masterData , который является an ObservableList и filteredData который также является an ObservableList .

Затем я хочу использовать его для отображения отфильтрованных данных при установке фильтра, а также для возможности восстановления при необходимости. Вот MCVE:

 package br;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class Main{
    private static ObservableList<Foo> masterData = FXCollections.observableArrayList();
    private static ObservableList<Foo> filteredData = FXCollections.observableArrayList();
    static Filter filter = new Filter();
    public static void addDummy(){
        masterData.add(new Foo("a",1));
        masterData.add(new Foo("aa",3));
        masterData.add(new Foo("b",2));
        masterData.add(new Foo("bb",4));
        masterData.add(new Foo("c",3));
    }
    public static void printData(ObservableList<Foo> list){
        for(Foo f: list) System.out.println(f.getName());
    }
    public static void main(String[] args) {
        addDummy();
        applyFilter(3);
        printData(filteredData);
        applyFilter(0);
        printData(filteredData);
    }
    public static void applyFilter(int num){
        filter.setData(masterData);
        filter.setFilter(num);
        filteredData = filter.getData();
    }
}
 

Фильтр класса, который я использую для фильтрации данных:

 package br;

import java.util.ArrayList;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class Filter {
    private ObservableList<Foo> data = FXCollections.observableArrayList();
    public void setFilter(int filter){
        List<Foo> copy = new ArrayList<Foo>(data);
        for(Foo f: copy)
            if(f.getBar()<filter) data.remove(f);
    }
    public ObservableList<Foo> getData() {
        return data;
    }

    public void setData(ObservableList<Foo> data) {
        this.data = data;
    }

}
 

И Foo класс, который представляет собой просто [String] name и [int] bar (плюс геттеры / сеттеры)

 package br;

public class Foo {
    private String name;
    private int bar;
    public Foo(String name, int bar){
        this.setBar(bar);
        this.setName(name);
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getBar() {return bar;}
    public void setBar(int bar) {this.bar = bar;}
}
 

Когда вы запустите этот код, вы получите:

aa
bb
c

Как когда фильтр был установлен на 3 (который фильтровал данные, как ожидалось), так и после того, как фильтр был «сброшен» на ноль.

Как я могу убедиться, что фильтр всегда обрабатывается с данными в MasterData, а затем сохраняется в filteredData ?

Примечание: это для проекта JavaFX, поэтому мне действительно нужно использовать ObservableList .

Ответ №1:

Проблема

 public void setData(ObservableList<Foo> data) {
    this.data = data;
}
 

Объяснение

В случае, если вам интересно, что Java подчиняется передаче по значению, и значение MasterData должно было быть скопировано в данные списка. Вы правы! Но в этой истории есть небольшой поворот !

В случае примитивов передаются значения, но в случае объектов ссылки на объекты передаются по значению.

Итак, вы ссылаетесь на объект MasterData, вместо того, чтобы копировать значения в новый список!

Решение

 this.data = FXCollections.observableArrayList(data);
 

Это создаст новый объект, на который будут ссылаться данные, и все манипуляции будут выполняться с данными этого нового объекта.

Комментарии:

1. Я просто хотел сказать, что это помогло мне, большое спасибо! Класс FXCollections очень полезен в нескольких экземплярах!