Implement Externalizable, so that you can save the most space

76 Views Asked by At

I have the class Element, which has the following attributes (see class). Since the range of the two integer values are very small, I want to store them in a short. This does not work for me. I want to work with the bitshifting. What am I doing wrong here? It is a school assignment, so it must be a short.


public class Element implements Externalizable {
    private static final long serialVersionUID = 6529685098267757690L;
    private boolean isMarked;
    private    boolean isValid;
   private boolean isDeleted;
    private int key; // VALUE AREA: 0-500
    private int value; // VALUE AREA: 1-10
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        short val =0;
        if(this.isMarked) val|=1;
        val <<=1;
        if(this.isValid) val|=1;
        val <<=1;
        if(this.isDeleted) val|=1;
        val <<=4;
        val |=  this.value;
        val <<=9;
        val |= (short) this.key;
        out.writeShort(val);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        short s = in.readShort();

        this.isMarked = s % 2==1;
        s >>= 1;
        this.isValid =s % 2==1;
        s >>>= 1;
        this.isDeleted = s % 2==1;
        s >>>= 4;
        this.value = s % 8;
        s >>>=9;
        this.value = s % 512;
    }

    @Override
    public String toString() {
        return "Element{" +
                "isMarked=" + isMarked +
                ", isValid=" + isValid +
                ", isDeleted=" + isDeleted +
                ", key=" + key +
                ", value=" + value +
                '}';
    }

    public Element(boolean isMarked, boolean isValid, boolean isDeleted, int key, int value) {
        this.isMarked = isMarked;
        this.isValid = isValid;
        this.isDeleted = isDeleted;
        this.key = key;
        this.value = value;
    }
    public Element(){}
}

1

There are 1 best solutions below

2
On

Read the data in reverse order. Use the binary and operator instead of the modulo operator, since short is signed. Negative numbers then lead to the problem described in your comment.

Change readExternal to:

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    short s = in.readShort();

    this.key = s & 511; // masks the lower 9 bits
    s >>>= 9;
    this.value = s & 15; // masks the lower 4 bits
    s >>>= 4;
    this.isDeleted = (s & 1) == 1; 
    s >>>= 1;
    this.isValid = (s & 1) == 1;
    s >>>= 1;
    this.isMarked = (s & 1) == 1;
}