2016-12-01 2 views
1

J'ai deux listes:Design API unique pour deux types différents

List<Date> list1 = new ArrayList<Date>(); 
List<WDate> list2 = new ArrayList<WDate>(); 

Je veux supprimer certains objets de ces listes. Cette fonctionnalité est présente dans une classe util.

public static List<Date> removeFromList1(List<Date> dateList) 
{ 
    Iterator<Date> dateItr = dateList.iterator(); 
    while(dateItr.hasNext()) 
    { 
     Date date = dateItr.next(); 
     if(date.compareTo(currentDate) <= 0) 
      dateItr.remove(); 
    } 

    return dateList; 
} 

public static List<WDate> removeFromList2(List<WDate> dateList) 
{ 
    Iterator<WDate> dateItr = dateList.iterator(); 
    while(dateItr.hasNext()) 
    { 
     WDate date = dateItr.next(); 
     if(date.getDate().compareTo(currentDate) <= 0) 
      dateItr.remove(); 
    } 

    return dateList; 
} 

class WDate 
{ 
    Date date; 
    Date getDate() { return date;} 
} 

Comment créer une méthode utilitaire unique pour servir les listes?

+0

Vous devriez savoir mieux que de poser une question aussi vague. – shmosel

+0

Peut-être fournir quelques informations sur 'A' et' B' et montrer un exemple d'implémentation de vos méthodes. – shmosel

+0

Vous pouvez utiliser des génériques pour le type d'élément de la liste –

Répondre

2

Voici une solution possible:

public static <T extends Comparable<T>> List<T> removeFromList(List<T> list, T current) 
{ 
    Iterator<T> itr = list.iterator(); 
    while(itr.hasNext()) 
    { 
     T elm = itr.next(); 
     if(elm.compareTo(current) <= 0) 
      itr.remove(); 
    } 

    return list; 
} 

...

class WDate implements Comparable<WDate> 
{ 
    Date date; 
    Date getDate() { return date;} 

    public WDate(Date date) { 
     this.date = date; 
    } 
    @Override 
    public int compareTo(WDate other) { 
     return date.compareTo(other.date); 
    } 
} 

MISE À JOUR:

Si vous voulez éviter la mise en œuvre de l'interface Comparable, vous pouvez fournir un comparateur pour removeFromList:

public static <T> List<T> removeFromList(List<T> list, T current, 
     Comparator<T> comp) { 
    Iterator<T> itr = list.iterator(); 
    while(itr.hasNext()) 
    { 
     T elm = itr.next(); 
     if(comp.compare(elm, current) <= 0) 
      itr.remove(); 
    } 
    return list; 
} 

MISE À JOUR 2 (pour davidxxx)

public static List<Date> removeFromList1(List<Date> dateList) 
{ 
    return removeFromList(dateList, currentDate.getDate()); 
} 

public static List<WDate> removeFromList2(List<WDate> dateList) 
{ 
    return removeFromList(dateList, currentDate); 
} 
+0

Idée intéressante mais elle a quelques limites. Vous fournissez un nouveau paramètre qui se trouve à l'origine dans la classe d'utilitaire. Ce paramètre représente la date réelle. L'ajout de ce paramètre rend certaines données internes visibles par le client. De plus, cela oblige le client à ajouter ce second paramètre à chaque appel. Enfin, s'il est mal utilisé, l'utilisateur pourrait fournir une autre date, qui pourrait ne pas convenir. – davidxxx

+0

@davidxxx OK, je vois la flexibilité supplémentaire comme un avantage. Vous pouvez toujours ajouter des fonctions d'assistance qui s'appelleront celle-ci. –

+0

Dans votre méthode d'aide, vous devriez faire un 'if else if' pour envoyer une date du jour avec le type approprié:' Date' ou 'WDate' puisque vous devriez appeler la méthode' compote() 'avec l'instance spécifique si vous voulez que la comparaison fonctionne. – davidxxx

1

Comme vous ne pouvez pas introduire une interface commune pour les deux types de Date (java.util.date étant non modifiable), vous ne pouvez pas avoir une seule méthode qui aurait la sécurité apportée par un génériques fins utilisent: l'unique ancêtre commun est Object ...
Personnellement, je pense que vous devriez garder les deux méthodes qui sont les plus propres avec vos contraintes.
Pourquoi? Je vais essayer d'expliquer les risques.
Si vous utilisez une seule méthode, comme vous l'avez dit, vous ne disposez pas de la sécurité de type et vous augmenterez les responsabilités de votre méthode d'assistance car elle devrait effectuer une vérification de type avant de pouvoir effectuer ses traitements.

Par exemple, vous pouvez faire:

public static <T> List<T> removeFromList(List<T> dateList) { 

    Iterator<T> dateItr = dateList.iterator(); 

    while (dateItr.hasNext()) { 
    T date = dateItr.next(); 

    // check if null value otherwise illegalArgumentexception may be thrown 
    if (date == null) { 
     continue; 
    } 

    // check types 
    boolean isEquals = false; 
    if (date instanceof Date) { 
     if (currentDate.equals(date)) { 
     isEquals = true; 
     } 
    } 
    else if (date instanceof WDate) { 
     WDate wDate = (WDate) date; 
     if (currentDate.equals(wDate.getDate())) { 
     isEquals = true; 
     } 
    } 
    // if unexpected type, we rise an exception 
    else { 
    throw new IllegalArgumentException("type not supported=" + date.getClass()); 
    }  

    //perform removing 
    if (isEquals){ 
     dateItr.remove(); 
    } 
    } 

    return dateList; 
} 

et maintenant vous appelez la méthode comme ceci:

List<WDate> wdates = new ArrayList<>(); 
WDate wdate = new WDate(); 
wdates.add(wdate); 
removeFromList(wdates); 

Le problème est que vous pouvez la méthode avec tout type dans la liste maintenant:

List<String> strings = new ArrayList<>(); 
String string = new String(); 
strings.add(string); 
removeFromList(strings); 

Ainsi, certaines erreurs qui ont pu être détectées au moment de la compilation ne seront détectées qu'à l'exécution. n le IllegalArgumentException sera levé.