我想创建一个包含大约60个double类型字段的类。然后我需要创建这个类的不同实例,只通过构造函数来评估其中一些字段(大约4-5个字段),将其他字段保留为默认值(0)。
问题在于我不想拥有60个参数构造函数,因为填充所有必需字段会浪费时间。此外,我不想创建公共方法来逐个设置字段值。
我正在考虑java Annotation,像
那样StatusListener statusListener = new StatusListener() {
@Override
public void onStatus(Status status) {
//your code to manage the statuses
}
//other requiredly-overriden methods
}
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.setOAuthConsumerKey("XXXXX");
configurationBuilder.setOAuthConsumerSecret("XXXXXXX");
TwitterStream twitterStream = new TwitterStreamFactory(configurationBuilder.build()).getInstance(new AccessToken("XXXXX", "XXXXXXX"));
twitterStream.addListener(statusListener);
//from here is different at your code
//you need to set up your user list, with their users id's!
long[] userslist = YOUR USER LIST;
//then you create a filter
FilterQuery filtre = new FilterQuery();
//and use that filter to follow the users that you want and to start the stream
filtre.follow(userslist);
twitterStream.filter(filtre);
这样我就可以只指定我需要的参数
public @interface MyAnnotation{
public double f1() default 0;
public double f2() default 0;
public double f3() default 0;
...
public double f60() default 0;
}
无论如何,我没有太多的经验,我不确定它能否应付我的需求。从广义上讲,我的目标是:
@MyAnnotation(f1=2.1 , f48=3.5)
有没有一种方法可以使用类构造函数来获得类似的东西?
P.S。我不是程序员,但我非常了解Java反射,所以如果需要它们就没问题。
答案 0 :(得分:1)
这样的东西?或者我离开了?
public class Blank{
public void Blank(int [] fSpots, double[] vaules0{
}
然后循环设置特定点等于值?
答案 1 :(得分:1)
查看“构建器”解决方案。您创建了一个镜像主类的可变类,每个字段都有setter(可能使用流畅的api以便于访问),然后让主不可变类将构建器作为参数并从中复制数据。 为避免手动创建庞大的构建器,您可以使用一些帮助程序,例如 https://projectlombok.org/features/Builder.html
或者,您可以使用groovy http://docs.groovy-lang.org/latest/html/documentation/#_named_argument_constructor 斯卡拉 http://docs.scala-lang.org/tutorials/tour/named-parameters.html 或者使用其中一个活动注释进行xtend。
答案 2 :(得分:0)
一种方法是实现不同的构造函数,每个构造函数只包含应填充的一些字段。如果您只想使用一些合理的值组合,这是一种有价值的方法。
此外,可以使用存储值的Map,将所有未存储的值解释为零。这个映射可以作为参数提供给构造函数。
一般来说,如果遇到如此庞大的数据类,就应该考虑设计。也许它应该被分成几个类用于不同的目的,也许不同的数据结构,如数组,映射或集合是合适的。
答案 3 :(得分:0)
我相信fluent interface可以帮到你。请记住,Java中double的默认值已经是0.0。
public class MyClass {
double f1;
double f2;
public MyClass() {
}
public MyClass f1(double f1) {
this.f1 = f1;
return this;
}
public MyClass f2(double f2) {
this.f2 = f2;
return this;
}
}
public class Test {
MyClass myClass1 = (new MyClass()).f1(1);
MyClass myClass2 = (new MyClass()).f2(2);
MyClass myClass3 = (new MyClass()).f1(1).f2(2);
}
答案 4 :(得分:0)
这很疯狂,但是:
enum Field {
F1, F2, F3, F48;
Arg set(Double value)
{
return new Arg(this, value);
}
static final class Arg
{
final Field field;
final Double value;
private Arg(Field f, Double v)
{
this.field = f;
this.value = v;
}
}
}
final class BadModel
{
private static final Double ZERO = (double) 0;
private final Map<Field, Double> fields = new EnumMap<>(Field.class);
BadModel(Field.Arg... args)
{
for (Field.Arg e : args)
this.fields.put(e.field, e.value);
}
Double get(Field field)
{
return fields.getOrDefault(field, ZERO);
}
public static void main(String... argv)
{
BadModel obj = new BadModel(Field.F1.set(2.1), Field.F48.set(Math.PI));
double f3 = obj.get(Field.F3);
System.out.println(f3);
}
}
我鼓励你退后一步,在假设有稀疏字段的对象是答案之前,先解决你的根本问题。
答案 5 :(得分:0)
我还没找到我想要的东西。无论如何,我发布了我选择的解决方案以防万一有人感兴趣。
我在内部创建了一个Class
Fields
:
public class MyClass{
double f1;
double f2;
...
double fn;
}
然后我创建了一个Enum
嵌入getFieldName()
方法,该方法返回String
等于MyClass
field
名称:
public enum MyEnum{
F1("f1"),
F2("f2"),
...
FN("fn");
private String name;
private MyEnum(String fieldName){
name = fieldName;
}
public String getFieldName(){
return name;
}
}
然后我为MyClass
创建了一个构造函数,利用java reflections
,将值设置为指定的字段。
public class MyClass{
double f1;
double f2;
...
double fn;
public MyClass(MyEnum[] fieldsName, double[] values){
for(int i=0; i<fieldsName.lenght; i++){
try{
Field f = this.getClass().getDeclaredField(fieldsName[i].getFieldName());
f.set(this,values[i])
}catch(Exception e){
e.printStackTrace();
}
}
}
}