2017-06-03 11 views
1

Werfen wir einen Blick auf mein Programm. Das hat eine imaginäre .txt-Datei mit Automodellen.Java Boolean Gleichungen als Parameter der Funktion

public class Car { 
    private String model; 

    public String getModel() { 
     return this.model; 
    } 
} 

public class Main { 
    public static void Main(String[] args) { 
     ArrayList<Car> cars = loadCars(path); //imaginary func and file 
     String someModel = generateSomeModel(); //imaginart func 

     for (Car c : cars) 
      if (c.getModel.equals(someModel)) 
       System.out.println("Hit!"); 

     for (Car c : cars) 
      if (!c.getModel.equals(someModel)) 
       System.out.println("Hit!"); 

    } 
} 

Lets nehme an, dass ich gehen durch meine Autos 100 mal auflisten und vergleichen sie in if-Anweisung für einige andere Attribute jedes Mal, das bedeutet, werde ich für verschiedene 100-Schleifen schreiben müssen, die 90% betragen gleich. Gibt es eine Möglichkeit, eine Funktion zu schreiben, die als Boolesche Gleichung eines Parameters dient? Etwas wie das.

public static void printCars(Boolean equation) { 
    for (Car c : cars) 
     if (Boolean equation) 
      System.out.println("Hit!"); 
} 
+1

Ich erkenne jetzt, dass Sie Ihre Frage nicht als Java-8 markiert haben. Sind Sie auf Java 8 oder verwenden Sie eine frühere Version? –

Antwort

2

Sie Prädikats Schnittstelle verwenden können, eine Funktion (oder Lambda) als Parameter an die Funktion zu übergeben:

https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html

Mit einem Prädikat Sie Ihre Funktion in folgender Weise umschreiben kann:

public static void printCars(Predicate<Car> filter) { 
    for (Car c : cars) 
     if (filter.test(car)) 
      System.out.println("Hit!"); 
} 

Und dann gewünschte Funktion in der folgenden Art und Weise passieren:

printCars(c -> c.getModel().equals("bmw"));

+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz zur Verfügung zu stellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - [Aus Bewertung] (/ review/low-quality-posts/16318885) –

+0

@AryaMcCarthy Zustimmen, fehlender Teil hinzugefügt. Vielen Dank! –

+0

Sollte 'filter.test (auto)' sein. – shmosel

0

Im Fall, dass Sie Ihnen Autos mit mehreren Attributen zu vergleichen, müssen Sie nur gleich Methode für Auto Klasse außer Kraft zu setzen.

@Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj instanceof Car) { 
      Car anotherCar = (Car)obj; 
      return this.model.equals(anotherCar.model) && 
        this.color.equals(anotherCar.color) && 
        this.year == anotherCar.year; 
     } 
     return false; 
    } 

Auf diese Weise können alle notwendigen Attribute in einem Schritt vergleichen werden:

List<Car> cars = //cars list 
Car someCar = //bmw car 
for (Car c : cars) { 
    if (c.equals(someCar)) { 
     System.out.println("Hit!"); 
    } else { 
     System.out.println("Another Hit!"); 
    } 
} 
2

Wenn Sie auf Java 8 sind, könnten Sie die Stream API mit einem Predicate verwenden:

cars.stream() 
    .filter(c -> c.getModel().equals(someModel)) 
    .forEach(c -> System.out.println("Hit!")); 

Das Argument der Stream.filter-Methode ist eine Predicate, die als ein Lambda-Ausdruck ausgedrückt wird, in diesem Fall car -> someModel.equals(car.getModel()).

Sie können die Lambda-Ausdruck ändern Sie Ihr zweites Beispiel zum Spiel:

cars.stream() 
    .filter(c -> !c.getModel().equals(someModel)) 
    .forEach(c -> System.out.println("Hit!")); 

Die Art und Weise zu abstrahieren diese ein Verfahren, um die Liste zu übergeben, das Prädikat, und wenn Sie möchten, ein Consumer, die nehmen etwas Aktion auf die passenden Elemente. Hier ist ein Code, den Sie als Ausgangspunkt verwendet werden könnte:

public static void handleCars(
     List<Car> cars, 
     Predicate<Car> condition, 
     Consumer<Car> action) { 

    cars.stream().filter(condition).forEach(action); 
} 

Sie diese Zeile Code lesen als: die Liste der Autos streamen, Filter nur die Autos, die den gegebenen Zustand und für jeden überein von ihnen, nehmen Sie die gegebene Handlung.

Und Sie können die handleCars Methode aufrufen wie folgt:

handleCars(
    cars, 
    c -> c.getModel().equals(someModel), 
    c -> System.out.println("Car with model " + someModel + " hit!")); 

Oder:

handleCars(
    cars, 
    c -> c.getBrand().toLowerCase().contains("mercedes"), // assume brand is String 
    c -> System.out.println("Mercedes model found: " + c.getModel())); 

Wie Sie sehen, die Prädikate und die Verbraucher können so komplex sein, wie Sie benötigen.