Перегрузка функции Java параметром List

у меня 2 класса

public class Customer{
  ...
  public String getCustomerNumber();
  ...
}

public class Applicant{
   ....
   private Customer c;
   public Customer getCustomer(){ return c; }
   ...
}

при представлении списка клиентов или заявителей мне нужна функция, которая повторяет список и делает что-то с CustomerNumber.

Я попытался перегрузить функцию

public void processCustomerNumbers(List<Customer> custList)
...

public void processCustomerNumbers(List<Applicant> appList)
...

но они рассматриваются как повторяющиеся методы... есть ли хороший способ сделать это, а не просто иметь 2 по-разному именованных функций?

6 ответов


Если вы делаете оба класса реализуют общий интерфейс,

interface CustomerNumber {
    String getCustomerNumber();
}

public class Customer implements CustomerNumber {
  ...
  public String getCustomerNumber();
  ...
}

public class Applicant implements CustomerNumber {
   ....
   private Customer c;
   public Customer getCustomer() { return c; }
   public String getCustomerNumber() { return getCustomer().getCustomerNumber(); }
   ...
}

тогда вы можете сделать то, что хотите, только одним методом:

public void processCustomerNumbers(List<? extends CustomerNumber> appList) {
    for (Customer c: appList) {
        processCustomerNumber(c.getCustomerNumber());
    }
}

дело в дженериках в Java заключается в том, что общие типы стираются во время выполнения, поэтому оба этих метода компилируются с одной и той же сигнатурой. Вам нужно будет иметь отдельные имена методов или проверить тип элементов списка во время выполнения.


дженерики имеют то, что известно как стирания типа - List<Customer> и List<Applicant> являются одним и тем же типом, компилятор просто устанавливает ограничения времени компиляции на то, что вы можете с ними сделать.

вы можете проверить тип первого объекта в списке и вызвать (с другим именем) внутренний метод на основе этого.


один из способов обойти эту проблему - определить пользовательские типы списков следующим образом:

class CustomerList extends ArrayList<Customer> {
    ...
}

class ApplicantList extends ArrayList<Applicant> {
    ...
}

тогда следующая перегрузка будет законной:

public void processCustomerNumbers(CustomerList custList)

public void processCustomerNumbers(ApplicantList appList)

однако я не думаю, что это была бы хорошая идея. Для начала он подключает определенные классы реализации в API вашего приложения.

лучшим подходом является определение общего интерфейса для клиента и заявителя, который позволяет обрабатывать их с помощью одного processCustomerNumbers метод. (Как описано в других ответах.)


вместо этого используйте массив.

public void processCustomerNumbers(Customer[] custList)
...

public void processCustomerNumbers(Applicant[] appList)
...

при попытке вызвать эти методы со списком, преобразовать список в массив:

List<Customer> customers;
List<Applicant> applicants;
...
processCustomerNumbers(customers.toArray(new Customer[]{});
processCustomerNumbers(applicants.toArray(new Applicant[]{});

прежде чем войти в имена методов , иерархия классов немного запутана...

public class Customer{          
  ...          
  public String getCustomerNumber();          
  ...          
}          

public class Applicant{          
   ....          
   private Customer c;          
   public Customer getCustomer(){ return c; }          
   ...          
}    

почему заявитель и клиент должны быть разные предметы ? Можешь сказать ... связь между этими объектами ?