2016-12-01 4 views
1

Ich habe zwei Listen:Designing einzigen API für zwei verschiedene Typen

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

Ich möchte einige Objekte aus diesen Listen entfernen. Diese Funktionalität ist in einer util-Klasse vorhanden.

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;} 
} 

Wie eine einzelne Dienstprogramm Methode erstellen sowohl die Listen zu dienen? Hier

+0

Sie sollten besser wissen, als eine so vage Frage zu stellen. – shmosel

+0

Vielleicht bieten einige Informationen über 'A' und' B' und zeigen eine Beispielimplementierung Ihrer Methoden. – shmosel

+0

Sie könnten Generika für den Elementtyp der Liste verwenden –

Antwort

2

ist eine mögliche Lösung:

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); 
    } 
} 

UPDATE:

Wenn Sie die vergleichbare Schnittstelle implementieren vermeiden wollen, können Sie einen Komparator liefern 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; 
} 

UPDATE 2 (für 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

Interessante Idee, aber es hat einige Grenzen. Sie stellen einen neuen Parameter bereit, der sich ursprünglich in der Dienstprogrammklasse befindet. Dieser Parameter repräsentiert das tatsächliche Datum. Durch Hinzufügen dieses Parameters werden einige interne Daten für den Client sichtbar. Außerdem zwingt es den Client, diesen zweiten Parameter bei jedem Aufruf hinzuzufügen. Endlich könnte der Benutzer ein anderes Datum angeben, das möglicherweise nicht geeignet ist. – davidxxx

+0

@davidxxx OK, ich sehe die zusätzliche Flexibilität als Vorteil. Sie können immer Hilfsfunktionen hinzufügen, die diesen aufrufen. –

+0

In Ihrer Hilfsmethode sollten Sie ein 'if else if' machen, um ein aktuelles Datum mit dem passenden Typ zu senden:' Date' oder 'WDate', da Sie' compare() 'method mit der spezifischen Instanz aufrufen sollten der Vergleich funktioniert. – davidxxx

1

Wie Sie nicht eine gemeinsame Schnittstelle für die zwei Arten von Date (java.util.date nicht veränderbar ist) vorstellen können, können Sie nicht eine einzige Methode haben, die die Sicherheit durch eine gebracht hätte Feine Generika verwenden: der einzige gemeinsame Vorfahre ist Object ...
Persönlich denke ich, dass Sie die beiden Methoden, die die sauberste Art und Weise mit Ihren Einschränkungen halten sollten.
Warum? Ich werde versuchen, Risiken zu erklären.
Wenn Sie eine einzige Methode verwenden, wie gesagt, Sie hätten keine Typsicherheit und Sie würden die Verantwortlichkeiten Ihrer Hilfsmethode erhöhen, da sie vorher eine Typprüfung durchführen sollte, um ihre Verarbeitungen durchführen zu können.

Zum Beispiel können Sie tun:

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; 
} 

und Sie nun die Methode wie folgt aufrufen:

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

Das Problem ist, dass man das Verfahren mit jeder Art in der Liste jetzt:

So werden einige Fehler, die zur Kompilierzeit entdeckt werden konnten, erst zur Laufzeit erkannt n IllegalArgumentException wird ausgelöst.

Verwandte Themen