2017-03-14 7 views
2

私のアプリケーションは、プロジェクト(Projectクラス)、およびEmployeesを持つ会社を代表しています。すべてEmployeeWorkerであり、LeaderはすべてWorkerであり、ProjectLeaderおよびDeveloperLeaderはすべてLeaderです。1つのジェネリック型引数を持つ1つのメソッドでインスタンスを収集して返す方法は?

Companyクラスのメソッドを作成します。このメソッドは型引数を受け取り、指定された型のすべてのインスタンスを含むSetを返します。同社は、すべてのプロジェクトを表現したプロジェクト、あります

private static Set<Project> projects = new HashSet<>(); 

を、すべてのプロジェクトは、プロジェクトのすべての労働者を代表する、リストを持っています

public List<Worker> workersOnProject = new ArrayList<>(); 

だから私は私の方法を受け入れることができるようにしたいです次の型引数:Project,Employee,Worker,Leader,ProjectLeader,DeveloperLeader。私の方法は次のとおりです。私は、たとえばprojectLeaderインスタンスを作成する場合

public <T> Set<T> getSameTypeEntity(Class<T> cls) { 
     Set<T> sameTypeEntities = new HashSet<>(); 
     if (cls == com.example.project.Project.class) { 
      sameTypeEntities.addAll((Collection<? extends T>) projects); 
     } else { 
      for (Project p : projects) { 
       for (Object e : p.workersOnProject) { 
        if (e.getClass() == cls) { 
         sameTypeEntities.add((T) e); 
        } 
       } 
      } 
     } 
     return sameTypeEntities; 
    } 

、私が使用します。Leader.classため

getSameTypeEntity(Leader.class); 
getSameTypeEntity(DeveloperLeader.class); 

ProjectLeader pL1 = new ProjectLeader(); 

をしかし、私はこのようなメソッドを呼び出すとき引数私のメソッドは空のSetを返しますが、それはDeveloperLeader.classのために働きます。したがって、スーパークラスの引数(EmployeeLeader)で呼び出すことはできません。Worker.classの場合は、このように作成されたインスタンスのみが戻されますが(Worker w1 = new Worker();)、であるため、すべてのLeaderサブタイプも返す必要があります。

「上位レベル」の引数を使用して呼び出すときに、どのようにすべてのサブクラスインスタンスを返すことができますか?私は確かではない、私は適切な方法でジェネリックを使用しているので、任意のクリーンなコードや使用法のアドバイスをいただきありがとうございます!

答えて

3

このセマンティクスに応じて、この小さな変更が必要な場合があります。

この置換:これに

if (e.getClass() == cls) { 

if(cls.isInstance(e)) 

に差は、これが完全に一致するだけでなく、チェックだけでなく、指定されたインタフェースを実装するサブクラスまたはクラスを可能にすることです。


そして、我々はそれでいる間:ここでは、

public <T> Set<T> getSameTypeEntity(Class<T> cls) { 
    Set<T> sameTypeEntities = new HashSet<>(); 
    if (cls == Project.class) { 
     sameTypeEntities.addAll((Collection<? extends T>) projects); 
    } else { 
     projects.stream() 
       .flatMap(p -> p.getWorkersOnProject().stream()) 
       .filter(cls::isInstance) 
       .map(cls::cast) 
       .forEach(sameTypeEntities::add); 
    } 
    return sameTypeEntities; 
} 
+0

はあなたに感謝し、より慣用のJava 8のスタイルで再書かれたあなたの方法です!まさに私が欲しかったもの:) – dmbdnr

関連する問題