如何正确使用泛型持有人

时间:2017-08-24 13:23:29

标签: java generics builder

我正在尝试为我的应用程序中使用的不同对象创建一个Holder类,我最终得到的代码在某种程度上工作正常,构建器模式适用于可选字段,但我想这个持有者可以被重构以接受任意数量的参数

package pojos;

public class Holder<T, R, S, U> {
private final T t;
private final R r;

private final S s;
private final U u;


private Holder(final Builder<T, R, S, U> builder) {
    this.t = builder.t;
    this.r = builder.r;
    this.s = builder.s;
    this.u = builder.u;
}


public T getField1() {
    return this.t;
}

public R getField2() {
    return this.r;
}

public S getField3() {
    return this.s;
}

public U getField4() {
    return this.u;
}


public static class Builder<T, R, S, U> {
    private T t;
    private R r;
    private S s;
    private U u;


    public Builder field1(final T t) {
        this.t = t;
        return this;
    }

    public Builder field2(final R r) {
        this.r = r;
        return this;
    }

    public Builder field3(final S s) {
        this.s = s;
        return this;
    }

    public Builder field4(final U u) {
        this.u = u;
        return this;
    }

    public Holder<T, R, S, U> build() {
        return new Holder<>(this);
    }

    public Builder<T, R, S, U> copy(final Holder<T, R, S, U> rowMappingsHolder) {
        this.t = rowMappingsHolder.getField1();
        this.r = rowMappingsHolder.getField2();
        this.s = rowMappingsHolder.getField3();
        this.u = rowMappingsHolder.getField4();
        return this;
    }


}

}

使用示例:

protected Holder<Row, Map<Integer, String>, Void, Void> getRowMapHolder(Row row, Map<Integer,String> map) {
    return (Holder<Row, Map<Integer, String>, Void, Void>) new Holder.Builder<Row, Map<Integer, String>,Void, Void>().field1(row).field2(map).build();
}

有什么想法吗?

此致

〜马科

2 个答案:

答案 0 :(得分:1)

这对于不同数量的参数应该如何工作?您拥有有限数量的访问者,因此如果您没有声明,则不能使用h.getField2147()

为不同数量的对象创建元组的另一种方法是异构数组。在Java,ofc中,你可以使用Object[],你可以用类包装它,它有方法

public <T> T getField(int i) { 
    return (T) arr[i]; 
}

然后像h.<String>getField(2147)

一样使用

但是为不同大小的元组创建不同的类(比如4个对象)更好。

答案 1 :(得分:0)

感谢Andy的评论和Google Autovalue,一个很好的解决方案出现了:

因此,我们可以创建具有意义的不同类,不再是&#34; field1&#34;,&#34; field2&#34; ...

SELECT *
FROM table
WHERE CASE WHEN work_start < work_end
      THEN @current_time BETWEEN work_start AND work_end
      ELSE @current_time >= work_start OR @current_time <= work_end
      END

package pojos;

import com.google.auto.value.AutoValue;
import org.apache.poi.ss.usermodel.Row;

import java.util.Map;

@AutoValue
public abstract class RowMapHolder {

    public abstract Row row();

    public abstract Map<Integer,String> mapping();

    public static RowMapHolder create(Row row, Map<Integer, String> mapping) {
        return new AutoValue_RowMapHolder(row, mapping);
    }

}