2017-08-24 36 views
1

我想为我的应用程序中使用的不同对象创建一个持有者类,我最终得到的代码在某种程度上正常工作,生成器模式对于可选字段,但我想这保持器可以被重构为接受任何任意数目的参数如何为持有人正确使用泛型

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(); 
} 

任何ID EAS?

问候

〜马尔科

+0

“任意数量的参数”这些参数是相同类型的吗? –

+0

不,您可以看到持有者可以包含不同类型的对象,请参阅“使用示例”仅使用前两个,一个持有类型“Row”,第二个持有类型为“Map”的对象,因此这里的问题是如何创建一个持有者,我们可以传递多个类型并按照他们在Holder中插入的顺序检索它们,因此不再需要“field1”,“field2”... –

+0

如果您没有显式结构/您想要维护的值的集合,仅使用Map或Set作为持有者会更容易,并且如果有关该持有者的内容格式错误(丢失了所需的参数或其他内容),则抛出无效的参数异常 – Tezra

回答

0

感谢Andy的评论和谷歌Autovalue,很好的解决出现了:

因此,我们可以创建一个具有意义不同类别,没有更多的“字段1”,“字段2” ......

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); 
    } 

} 

package pojos; 

import com.google.auto.value.AutoValue; 

import java.util.List; 
import java.util.Map; 

@AutoValue 
public abstract class KeyValuesMapHolder { 

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

    public static KeyValuesMapHolder create(List<KeyValue<String, String>> keyValues, Map<Integer, String> mapping) { 
     return new AutoValue_KeyValuesMapHolder(keyValues, mapping); 
    } 

} 
1

应如何针对不同数量的参数工作?您的访问者数量有限,因此,如果您未声明,则无法使用,例如h.getField2147()

不同数量的对象具有元组的另一种方法是异构数组。在Java中,OFC,你可能只需要使用Object[],你可以用类,它有方法

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

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

但是,创造不同类别的不同大小的元组(如您的包裹它4个物体)更好。