QA@IT

javaでの質問です。

4304 PV

下記のEmployeeManagerクラスとUnitManagerクラスなのですが処理が似ています。
今後も同じようなメソッドを両方のクラスに追加していくのは面倒だと思いましたので、
スーパークラスを定義して(仮にManagerクラスとして)処理を共通化しようと試みたのですが、
型が異なるせいか私には定義できませんでした。(コメントアウト部分)

※java(静的型付け)初心者ですので検討違いなことを質問しているかもしれませんがお許し下さい。。
皆さんならどの様に処理を共通化されますか。

import java.util.ArrayList;

public class www {
    public static void main(String args[]) {
        int[] empPk = { 0, 1, 2 };
        String[] empName = { "山田", "佐藤", "石元" };
        int[] empFk = { 0, 1, 0 };

        int[] uniPk = { 0, 1 };
        String[] uniName = { "営業", "人事" };

        EmployeeManager empCreater = new EmployeeManager(empPk, empName, empFk);
        UnitManager uniCreater = new UnitManager(uniPk, uniName);
        System.out.println("名前:" + empCreater.get(0).getName());
        System.out.println("部署:" + uniCreater.get(empCreater.get(0).getFk()).getName());

    }
}

class EmployeeManager {
    private ArrayList<Employee> objs = new ArrayList<Employee>();

    public EmployeeManager(int[] pk, String[] name, int[] fk) {
        for (int i : pk) {
            objs.add(new Employee(i, name[i], fk[i]));
        }
    }

    public Employee get(int pk) {
        for (Employee obj : objs) {
            if (obj.getPk() == pk) {
                return obj;
            }
        }
        return null;
    }
}

class UnitManager {
    private ArrayList<Unit> objs = new ArrayList<Unit>();

    public UnitManager(int[] pk, String[] name) {
        for (int i : pk) {
            objs.add(new Unit(i, name[i]));
        }
    }

    public Unit get(int pk) {
        for (Unit obj : objs) {
            if (obj.getPk() == pk) {
                return obj;
            }
        }
        return null;
    }
}

/*
class Manager<T> {
    protected ArrayList<T> objs = new ArrayList<T>();

    protected T get(int pk) {
        for (T obj : objs) {
            if (obj.getPk() == pk) {
                return obj;
            }
        }
        return null;
    }
}

class EmployeeManager extends Manager<Employee> {

    public EmployeeManager(int[] pk, String[] name, int[] fk) {
        for (int i : pk) {
            objs.add(new Employee(i, name[i], fk[i]));
        }
    }
}

class UnitManager extends Manager<Unit> {

    public UnitManager(int[] pk, String[] name) {
        for (int i : pk) {
            objs.add(new Unit(i, name[i]));
        }
    }
}
*/
class Employee {
    private int pk;
    private String name;
    private int fk;

    public Employee(int pk, String name, int fk) {
        this.pk = pk;
        this.name = name;
        this.fk = fk;
    }

    public int getFk() {
        return fk;
    }

    public int getPk() {
        return pk;
    }

    public String getName() {
        return name;
    }

}

class Unit {
    private int pk;
    private String name;

    public Unit(int pk, String name) {
        this.pk = pk;
        this.name = name;
    }

    public int getPk() {
        return pk;
    }

    public String getName() {
        return name;
    }

}
  • そもそも、EmployeeManagerクラスとUnitManagerクラスは何のためのクラスなんですか?そこに書かれたコードを見る限り、そのクラスの実体はArrayListです。わざわざ定義する必要がないのでは? -
  • 先程、回答欄に返信してしまい失礼いたしました。
    ご指摘いただきありがとうございます!
    クラスにすることばかり意識してしまって、何のためのクラスかまでは考えていませんでした。ご指摘頂いた通りわざわざ定義する必要はないようですね。
    今回はArrayListもクラスでラップする方針だと仮定した場合としてご教示いただけますと幸いです。
    -
  • それから、EmpoyeeクラスとUnitクラスのpk変数(primary key?)は、なんのためのものですか?データベースと連携でもするんですか?それともただのインデックス番号? -
  • コメントありがとうございます。データベースと連携するイメージになります。 -

回答

そのprimary keyをkeyとしたMAPにしてしまえばいいと思います。

import java.util.*;

public class Main {

  static public void main(String[] args) {

    int[] empPk = { 0, 1, 2 };
    String[] empName = { "Yamada", "Satou", "Ishimoot" };
    int[] empFk = { 0, 1, 0 };

    HashMap<Integer,Employee> map = new HashMap<Integer,Employee>(3);
    for (int i = 0; i < empPk.length; i++) {
      Employee emp = new Employee(empPk[i], empName[i], empFk[i]);
      map.put(empPk[i], emp);
    }
    System.out.println(map);
  }
}
編集 履歴 (0)
  • ご回答いただきありがとうございます。大変参考になります!stripeさまにはそもそも的なところからいろいろとご指摘いただき感謝致します。 -

以下のようにすれば動作するようになります。
オブジェクトの管理方法をManager側で変更できるようにしたいという事なのでしょうが、
それによって生じている制約(getのせいでPKが1列で数値とか)は気になるところではありますね。

それはいろいろ検討してみるといいと思います。

class Manager<T extends IGetPK> {
    protected ArrayList<T> objs = new ArrayList<T>();

    public T get(int pk) {
        for (T obj : objs) {
            if (obj.getPk() == pk) {
                return obj;
            }
        }
        return null;
    }
}

class EmployeeManager extends Manager<Employee> {

    public EmployeeManager(int[] pk, String[] name, int[] fk) {
        for (int i : pk) {
            objs.add(new Employee(i, name[i], fk[i]));
        }
    }
}

class UnitManager extends Manager<Unit> {

    public UnitManager(int[] pk, String[] name) {
        for (int i : pk) {
            objs.add(new Unit(i, name[i]));
        }
    }
}

interface IGetPK{
    public int getPk();
}


class Employee implements IGetPK {
    private int pk;
    private String name;
    private int fk;

    public Employee(int pk, String name, int fk) {
        this.pk = pk;
        this.name = name;
        this.fk = fk;
    }

    public int getFk() {
        return fk;
    }

    @Override
    public int getPk() {
        return pk;
    }

    public String getName() {
        return name;
    }
}

class Unit implements IGetPK {
    private int pk;
    private String name;

    public Unit(int pk, String name) {
        this.pk = pk;
        this.name = name;
    }

    @Override
    public int getPk() {
        return pk;
    }

    public String getName() {
        return name;
    }
}
編集 履歴 (0)
  • 動作いたしました。ご教示ありがとうございます。お陰様でモヤモヤがスッキリしました。
    私にはclass Manager<T extends IGetPK> といった指定方法、全く思いつきませんでした。ファンタスティックです!継承やインタフェイス、ジェネリクス等の理解不足も痛感いたしました。本当にありがとうございました。
    -

誤って記入したため削除しました

編集 履歴 (1)
ウォッチ

この質問への回答やコメントをメールでお知らせします。