我一直在努力解决以下问题。我有一系列函数对象,每个对象都有自己的输入和输出类型,这些输入和输出类型是通过java中的泛型类型参数定义的。我想将它们排列成一个链,以便将原始数据输入到第一个函数,然后将其转换为输出类型,即下一个对象的输入类型,依此类推。当然,这对于硬代码来说是微不足道的,但是我希望代码可以插入到新的函数对象中。如果我只是忽略类型html" target="_blank">参数(仅最终输出类型),则外观如下:
public T process() {
Iterator<Context> it = source.provideData();
for(Pipe pipe : pipeline) {
it = pipe.processIterator(it);
}
return sink.next(it);
}
这里,数据的迭代器在函数对象之间传递,并且context应该是Context。有什么方法可以保持以下类型的管道可插拔并仍然保持类型安全?
编辑:为清楚起见,我有一系列功能对象,管道。每个都将特定类型作为输入并输出另一种类型。(实际上是这些类型的迭代器),它们将被链接在一起,例如Pipe<A,B> -> Pipe<B,C> -> Pipe<C,D> -> ...
,这样一个管道的输出就是下一个管道的输入类型。这里还有一个源,它输出类型为A的迭代器,以及一个接受类型的接收器(过去管道的输出)。这使事情更清楚了吗?问题是,由于严重依赖于输入和输出类型的兼容性,有没有办法确保这一点?
我开始认为将函数对象插入管道中可能是确保类型安全的最佳时间,但是我不确定如何做到这一点。
编辑2:我有一个函数对象的加法器方法,如下所示:
public void addPipe(Pipe<?,?> pipe) {
pipeline.add(pipe);
}
我想检查第一个类型参数是否与当前管道的“结束”相同,否则抛出异常?我不认为这里有一种获取编译时间安全的好方法。然后可以将当前管道的“末端”设置为输入管道的第二种参数。我想不出如何使用泛型来实现,并且传递类信息似乎很可怕。
这是一种方法。run方法不是类型安全的,但是鉴于附加管道的唯一方法是以类型安全的方式进行,因此整个链都是类型安全的。
public class Chain<S, T> {
private List<Pipe<?, ?>> pipes;
private Chain() {
}
public static <K, L> Chain<K, L> start(Pipe<K, L> pipe) {
Chain<K, L> chain = new Chain<K, L>();
chain.pipes = Collections.<Pipe<?, ?>>singletonList(pipe);;
return chain;
}
public <V> Chain<S, V> append(Pipe<T, V> pipe) {
Chain<S, V> chain = new Chain<S, V>();
chain.pipes = new ArrayList<Pipe<?, ?>>(pipes);
chain.pipes.add(pipe);
return chain;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public T run(S s) {
Object source = s;
Object target = null;
for (Pipe p : pipes) {
target = p.transform(source);
source = target;
}
return (T) target;
}
public static void main(String[] args) {
Pipe<String, Integer> pipe1 = new Pipe<String, Integer>() {
@Override
public Integer transform(String s) {
return Integer.valueOf(s);
}
};
Pipe<Integer, Long> pipe2 = new Pipe<Integer, Long>() {
@Override
public Long transform(Integer s) {
return s.longValue();
}
};
Pipe<Long, BigInteger> pipe3 = new Pipe<Long, BigInteger>() {
@Override
public BigInteger transform(Long s) {
return new BigInteger(s.toString());
}
};
Chain<String, BigInteger> chain = Chain.start(pipe1).append(pipe2).append(pipe3);
BigInteger result = chain.run("12");
System.out.println(result);
}
}
我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。
现在,当我在地图上迭代时…我能以某种方式获得每个Class1对象的类型(K,V)吗??
我学完了泛型,发现并不容易。不过,我确实理解了。这是我理解的。我要你纠正我错的地方,并回答几个问题:)。 null null null null null null null null 内部类也必须实现Serializable吗?
同样的规则也可以适用于函数:在使用前给出 <T> 后,类型 T 就变成了泛型。 使用泛型函数有时需要显式地指明类型参量。这种可能的情况包括,调用返回类型是泛型的函数,或者编译器没有足够的信息来推导类型参量。 函数调用使用显式指定的类型参量,如下所示: fun::<A, B, ...>(). struct A; // 具体类型 `A`。 struct S(A); //
问题内容: 这是我的基本功能: 此功能能够连接并在我的数据库上执行查询… 我想创建相同的功能,但更通用。…前一个仅用于一个表(),新表必须能够接受查询的参数作为输入,以及将在其中执行查询的类类型。这将允许我仅使用一行来执行查询。 应该是这样的: 您发现我不知道如何“通用”代码… 我希望已经清楚了… PS 应该是DB()中表的类的代表。 谢谢。 问题答案: 如果您打算返回结果集,请使用:
问题内容: 我想知道以下两个方法声明之间有什么区别: 有什么可以/可以做的,而不是另一种?我在本网站的其他地方找不到这个问题。 问题答案: 与上下文隔离-没有区别。在和两者上,您只能调用的方法。 但是有上下文-如果您有泛型类: 然后: 与对象相同的代码 两个优点: 无需强制转换(编译器向您隐藏了此内容) 编译有效的时间安全性。如果使用的是版本,则不能确保方法始终返回。如果返回,则在运行时会有一个。