[英]Is there a better and cleaner way to write this two functions?
所以我正在努力以一种干净的方式编写这段代码。 不知道有没有更好的办法。
private function1(Collection<D> collection) {
for (Iterator it = collection.iterator(); it.hasNext(); ) {
Object object = it.next();
switch (object .getClass().getSimpleName()) {
case "A": do some work with class A
break;
case "B": do some work with class B
break;
case "C": do some work with class C
break;
}
}
}
所以我得到了一个我迭代的集合。 但是集合可以是集合中的三个不同的类,因为 class A、B、C 是父 class D 的父类。我认为我的代码不干净,我正在寻找一个好方法。 这是我的另一个例子,它有点不同。
private function2(Collection<A,B,C> collection) {
for (Iterator it = collection.iterator(); it.hasNext(); ) {
Object object = it.next();
switch (object .getClass().getSimpleName()) {
case "A": do some work with class A
break;
case "B": do some work with class B
break;
case "C": do some work with class C
break;
}
}
}
In this function I can get either a collection of class A of class B or of class C. 我想为每个 class 创建三个单独的函数。 但比我有代码重复。 但我不知道将function2拆分为function2A,function2B,function2C是否会更好。
有没有更好更干净的方法来实现这两个功能。 A、B、C 和 D 类来自一个框架。 所以我无法编辑它们。
这是一个想法。 主要是将要处理的类列表与调用方法分开,因此您不必修改 switch 方法来添加其他类。 请注意, Collections 实现了Iterable
,因此您不需要显式迭代器。
它还假定您已经建立了方法来完成所需的工作。
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
public class WorkFunction {
Map<String, Consumer<Object>> fnc = Map.of(
"A", this::doWorkA,
"B", this::doWorkB,
"C", this::doWorkC);
public static void main(String[] args) {
WorkFunction wf = new WorkFunction();
List<Object> list = List.of(new A(), new B(), new A(), new A(),
new C(), new B(), wf);
wf.function1(list);
}
static class A {}
static class B {}
static class C {}
public <D> void function1(Collection<D> collection) {
for(D object : collection) {
fnc.getOrDefault(object.getClass().getSimpleName(),
(ob)->System.out.println("Who are you??")))
.accept(object);
}
}
public void doWorkA(Object ob) {
System.out.println("Working on A");
}
public void doWorkB(Object ob) {
System.out.println("Working on B");
}
public void doWorkC(Object ob){
System.out.println("Working on C");
}
}
印刷
Working on A
Working on B
Working on A
Working on A
Working on C
Working on B
Who are you??
您可以创建 A、B 和 C 可以实现的接口。 在您的界面中,您可以声明一个“完成工作”的方法,并且 A、B 和 C 可以有自己的实现。
interface MyInterface{
void doTheWork();
}
然后对每个 class 执行此操作
class A implements MyInterface {
void doTheWork() {
...
}
}
现在您可以遍历集合,而无需检查实例的 class
EDIT - If you cannot modify A,B, or C than you can use a map with the class as the key and a lambda as the value.
Map<Class,Runnable> lambdaClassMap = new HashMap<>();
lambdaClassMap.put(A.class, () -> doAWork(object));
lambdaClassMap.put(B.class, () -> doBWork(object));
lambdaClassMap.put(C.class, () -> doCWork(object));
//psuedocode
for(...) {
Object object = it.next();
lambdaClassMap.get(object.getClass()).run();
}
利用多态性避免需要确定它是哪个子类,以便为每个 class 做不同的工作。
向D
超类添加一个方法doWork
(或任何更合适的名称),并在所有子类A
、 B
和C
中实现它。 如果合适,它可以在D
中是abstract
的。
然后你的方法变成如下:
private void function1(Collection<? extends D> collection) {
for (Iterator<? extends D> it = collection.iterator(); it.hasNext(); ) {
D d = it.next();
d.doWork();
}
}
使用? extends D
? extends D
以便该方法可以接受Collection<D>
、 Collection<A>
、 Collection<B>
或Collection<C>
。 这也避免了原始的Iterator
。
您还可以使用等效的、更短的、增强的 for 循环:
private void function1(Collection<? extends D> collection) {
for (D d : collection) {
d.doWork();
}
}
您的第二种方法看起来就像第一种方法一样,只是它尝试使用没有意义的Collection<A, B, C>
。 Collection
只有一个类型参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.