有没有更好更简洁的方法来编写这两个函数?
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;
}
}
}
所以我得到了一个我迭代的集合。但是该集合可以是集合中的三个不同的 classes,因为 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;
}
}
}
在这个函数中,我可以获得 class A 或 class B 或 class C 的集合。我想为每个 [=20= 创建三个单独的函数].但是比我有代码重复。但是不知道把function2拆分成function2A,function2B,function2C是不是真的更好
有没有更好更简洁的方法来实现这两个功能。 类 A、B、C 和 D 来自一个框架。所以我无法编辑它们。
您可以创建 A、B 和 C 可以从中实现的接口。在您的界面中,您可以声明一个方法,该方法 'do the work' 并且 A、B 和 C 可以有自己的实现。
interface MyInterface{
void doTheWork();
}
然后对每个 class
执行此操作
class A implements MyInterface {
void doTheWork() {
...
}
}
现在您可以循环遍历集合而无需检查class实例属于
EDIT - 如果您无法修改 A、B 或 C,则可以使用以 class 作为键并以 lambda 作为值的映射。
//pseudocode
Map<Class<?>,Runnable> lambdaClassMap = new HashMap<>();
lambdaClassMap.put(A.class, () -> doAWork());
lambdaClassMap.put(B.class, () -> doBWork());
lambdaClassMap.put(C.class, () -> doCWork());
for(...) {
Object object = it.next();
lambdaClassMap.get(object.getClass()).run();
}
编辑#2 - 所以既然你想访问你的对象,而不是使用 Runnable
你可以使用 Function
.
// change the function do what you want
// this one accepts the A object and calls an imaginary method 'getSize()'
Function<A, Integer> funcA = x -> x.getSize();
Map<Class<?>,Function> functionClassMap = new HashMap<>();
functionClassMap.put(A.class, funcA));
现在,您可以在函数中使用 apply()
方法在循环时直接访问您的对象。
Integer size = functionClassMap.get(object.getClass()).apply(object);
利用多态性来避免需要确定它是哪个子class以便为每个class.
做不同的工作
向D
superclass添加一个方法doWork
(或任何你有的更合适的名称),并在所有subclass中实现它]es 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
以便该方法可以接受 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
只有一个类型参数。
这是一个想法。主要是它将要处理的 classes 列表与调用方法分开,因此您不必修改 switch 方法来添加其他 classes。请注意,集合实现 Iterable
因此您不需要显式迭代器。
它还假设您已经建立了完成所需工作的方法。
- 构建名称到要调用的方法的映射。这部分将替换您的 switch 语句。
- 它使用默认方法来捕获未知的 class 名称,如果它们出现
- 它们只是迭代,处理对象。
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??
所以我正在努力以干净的方式编写这段代码。不知道有没有更好的方法。
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;
}
}
}
所以我得到了一个我迭代的集合。但是该集合可以是集合中的三个不同的 classes,因为 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;
}
}
}
在这个函数中,我可以获得 class A 或 class B 或 class C 的集合。我想为每个 [=20= 创建三个单独的函数].但是比我有代码重复。但是不知道把function2拆分成function2A,function2B,function2C是不是真的更好
有没有更好更简洁的方法来实现这两个功能。 类 A、B、C 和 D 来自一个框架。所以我无法编辑它们。
您可以创建 A、B 和 C 可以从中实现的接口。在您的界面中,您可以声明一个方法,该方法 'do the work' 并且 A、B 和 C 可以有自己的实现。
interface MyInterface{
void doTheWork();
}
然后对每个 class
执行此操作class A implements MyInterface {
void doTheWork() {
...
}
}
现在您可以循环遍历集合而无需检查class实例属于
EDIT - 如果您无法修改 A、B 或 C,则可以使用以 class 作为键并以 lambda 作为值的映射。
//pseudocode
Map<Class<?>,Runnable> lambdaClassMap = new HashMap<>();
lambdaClassMap.put(A.class, () -> doAWork());
lambdaClassMap.put(B.class, () -> doBWork());
lambdaClassMap.put(C.class, () -> doCWork());
for(...) {
Object object = it.next();
lambdaClassMap.get(object.getClass()).run();
}
编辑#2 - 所以既然你想访问你的对象,而不是使用 Runnable
你可以使用 Function
.
// change the function do what you want
// this one accepts the A object and calls an imaginary method 'getSize()'
Function<A, Integer> funcA = x -> x.getSize();
Map<Class<?>,Function> functionClassMap = new HashMap<>();
functionClassMap.put(A.class, funcA));
现在,您可以在函数中使用 apply()
方法在循环时直接访问您的对象。
Integer size = functionClassMap.get(object.getClass()).apply(object);
利用多态性来避免需要确定它是哪个子class以便为每个class.
做不同的工作向D
superclass添加一个方法doWork
(或任何你有的更合适的名称),并在所有subclass中实现它]es 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
以便该方法可以接受 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
只有一个类型参数。
这是一个想法。主要是它将要处理的 classes 列表与调用方法分开,因此您不必修改 switch 方法来添加其他 classes。请注意,集合实现 Iterable
因此您不需要显式迭代器。
它还假设您已经建立了完成所需工作的方法。
- 构建名称到要调用的方法的映射。这部分将替换您的 switch 语句。
- 它使用默认方法来捕获未知的 class 名称,如果它们出现
- 它们只是迭代,处理对象。
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??