簡體   English   中英

有沒有更好更簡潔的方法來編寫這兩個函數?

[英]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 ,因此您不需要顯式迭代器。

它還假定您已經建立了方法來完成所需的工作。

  • 構建一個名稱為 map 的方法來調用。 這部分替換了您的 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??

您可以創建 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 (或任何更合適的名稱),並在所有子類ABC中實現它。 如果合適,它可以在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM