0

I need to extend AbstractTableModel to represent some data in a table. I have a class Car which should represent one item (row) in a table:

public class Car implements Comparable<Car> {
    public String make;
    public int year;
    public double engineVol;
    public double maxSpeed;

    // ...getters/setters for the fields...


    public Car (String make, int year, double engineVol, double maxSpeed) {
        this.make = make;
        this.year = year;
        this.engineVol = engineVol;
        this.maxSpeed = maxSpeed;

    }

    @Override
    public boolean equals(Object other) {
        if (this == other) return true;
        if (other == null || getClass() != other.getClass()) return false;

        Car car = (Car) other;

        if (year != car.year) return false;
        if (Double.compare(car.engineVol, engineVol) != 0) return false;
        if (Double.compare(car.maxSpeed, maxSpeed) != 0) return false;
        return make.equals(car.make);
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        result = make.hashCode();
        result = 31 * result + year;
        temp = Double.doubleToLongBits(engineVol);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(maxSpeed);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public int compareTo(Car other) {
        return this.make.compareTo(other.make);
    }
}

These Car objects are stored in a HashSet, which resides in the CarTableModel:

public class CarTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 7927259757559420606L;
    private HashSet<Car> cars;

    public CarTableModel(HashSet<Car> cars) {
        this.cars = cars;
    }

    @Override
    public int getRowCount() {
        return cars.size();
    }

    @Override
    public int getColumnCount() {
        return 4;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return null;
    }
}

As far as I get it I need to override at least 3 methods in an AbstractTableModel. How do I override getValueAt for a HashSet? What are those rowIndex and columnIndex arguments concerning the HashSet? How are those indeces are applied to the HashSet if we cannot get values from one by an index? Is it possible at all?

P.S. It's not my caprice to use a HashSet here, it's a university assignment, so it has to go this way.

yabee-dabee
  • 106
  • 2
  • 5
  • Did you read the javadocs? I'm pretty sure it explains it there. – pczeus Mar 13 '16 at 19:28
  • 5
    The notion of index makes no sense for a HashSet. That's pretty much it. – Tunaki Mar 13 '16 at 19:28
  • @Wannabee, why are you using a HashSet instead of a List implementation? – josivan Mar 13 '16 at 19:34
  • @josivan It's a university home assignment with rather rigid restrictions as to what collections and classes are to be used. Each student gets his own combo of collection/data-class/sorting direction/and some other options. I would not even bother with a HashSet here if it was up to me – yabee-dabee Mar 13 '16 at 19:55
  • I've answered your question with an a possible approach, Let me know if you need some extra help. – josivan Mar 13 '16 at 20:08

4 Answers4

2

How do I override getValueAt for a HashSet?

Don't use a HashSet. You would typically use an ArrayList so the rows are defined in the order you add them to the List.

For example check out Table Row Model which walks through the process of creating a custom model. It also provide a generic TableModel to make the process simpler if you wish.

It's not my caprice to use a HashSet here, it's a university assignment, so it has to go this way.

Missed that comment. I have no idea why you would be required use a HashSet since there is no direct way to access the data. So it seems to me like you need to iterate through the Set every time a row is required. Not very efficient.

camickr
  • 321,443
  • 19
  • 166
  • 288
1

You can try to use LinkedHashSet. But it is unclear how to use columnIndex with Car.

Maybe, ArrayTable from guava will help you.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67
1

You'll have to know that even if you think of using a Iterator to get to the nth value of your HashSet, the order is undefined.

Here, from the JavaDoc

It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.


Though, if you really have to use this collection, here is an implementation of getValueAt

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Optional<Car> tmpCar = cars.stream()
                               .skip(rowIndex) // Assuming your rows begin with 0
                               .findFirst();
    return tmpCar.isPresent() ? tmpCar : null;
}
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
0

So, if is mandatory for you to use HashSet, you can do something like that:

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Car car = null;
    int = 0;
    for (Car c : cars) {
        if (i == rowIndex) {
            car = c;
            break;
        }
        i++;
    }
    if (car == null) // handle this situation with your rules
        return "";

    return car.get<Field as described in your columns>; //
}

Bear in mind that is not guaranteed the order. Then test it a lot.

josivan
  • 1,963
  • 1
  • 15
  • 26