2016-01-28 157 views
-2

好日子搜索在ArrayList中的特定對象,通過屬性

想象我有以下代碼: (這些顯然不是所有的屬性)

class Owner { 
    private String name; 
} 

class Car { 
    private Owner owner; 
    private String brandName; 

    public boolean isClean() { // not included in the contructor 
     return false; 
    } 

class FuelCar extends Car { 
    private String fuelType; 

    public boolean isClean() { 
     if (fuelType.equals("Diesel")){ 
      return false; 
     } else { 
      return true; 
    } 
} 

class ElectricCar extends Car { 
    private int batteryLevel; 

    public boolean isClean() { 
     return true; 
    } 
} 

的對象添加到一個ArrayList:

ArrayList<Car> cars = new ArrayList<>(); 

實例:

cars.add(new Auto("Audi", new Owner("Peter"))); 
cars.add(new Auto("Fiat", new Owner("Rob"))); 
cars.add(new Auto(Mercedes, null)); 
cars.add(new ElectricCar(10, "Opel ", new Owner("Unknown"))); 
cars.add(new ElectricCar(100,"Google", new Owner("Google"))); 
cars.add(new FuelCar("diesel", "Seat", new Owner("Tom"))); 
cars.add(new FuelCar("gasonline", "Smart", new Owner("Marcel"))); 

現在的問題是:

  1. 我怎樣才能讓一個方法,所以我只列出其中具有值isClean「真」的所有汽車;

  2. 如何使具有以下簽名的方法: 公共靜態無效printCarsSpecific(ArrayList的汽車,字符串fuelType) 因此,舉例來說,如果我把在: printCarsSpecific(「汽油」); 打印ArrayList時只顯示那些汽車。

PS:這不是功課。只爲教育 我自己輸入了上面的代碼,並沒有複製和粘貼,因爲它會變大。

我嘗試以下方法:

public static void printBedrijfsautosMetType(ArrayList<Auto> autos, String brandstof) { 
    Iterator<Auto> iter = autos.iterator(); 
    while (iter.hasNext()) { 
     Auto auto = iter.next(); 

     if (auto instanceof BrandstofAuto) { 
      String brandstof1 = ((BrandstofAuto) auto).getBrandstof(); 
      if (!brandstof1.equals(brandstof) || brandstof1 == null) { 
       iter.remove(); 
      } 
     } 
     for (int i = 0; i < autos.size(); i++) { 
      System.out.println(autos.get(i)); 
     } 

    } 
} 

public static void printSchoneAutos(ArrayList<Auto> autos) { 
     Iterator<Auto> iter = autos.iterator(); 
     while (iter.hasNext()) { 
      Auto auto = iter.next(); 
      if (auto instanceof BrandstofAuto) { 
       boolean isschoon = ((BrandstofAuto) auto).isSchoon(); 
       boolean isschoon3 = auto.isSchoon(); 
       if (isschoon3 == false || isschoon == false) { 
        iter.remove(); 
       } 
      } 
      for (int i = 0; i < autos.size(); i++) { 
       System.out.println(autos.get(i)); 
      } 
     } 
    } 

我想我沒有刪除這些項目,因爲我已經通過例子在這裏看到。

+0

你嘗試過什麼嗎? – proskor

+0

@ R.Schouten您至少應該首先縮進您的代碼。此外,你的語法是錯誤的,爲什麼像'class'和'private'這樣的詞彙是大寫的?在我看來,你甚至不知道基本知識。也許你應該發佈你到目前爲止嘗試過的東西。 – user3437460

+3

這確實看起來像一個家庭作業... –

回答

0

這似乎是一個家庭作業,但我會咬。

最簡單的方法是迭代原始列表並從中選擇匹配的項目。

ArrayList<Car> cleanCars = new ArrayList<Car>(); 
for (Car car : scars) { 
    if (car.isClean()) { 
     cleanCars.add(car); 
    } 
} 

一個顯然會創建一個對象來包裝汽車的收藏。也許類似CarCollection,這本身就換一個集合對象像ArrayList


該問題的第二部分看起來像是XY Problem。你爲什麼要混合過濾收集的汽車物體並將其打印出來的邏輯? (除了,你知道,如果它是一項家庭作業)。數據排序邏輯和表示邏輯應該儘可能分開。

取而代之的是以下內容:

public static void printCarsSpecific(ArrayList Cars, String fuelType)

爲什麼不能有一個過濾器的汽車名單的方法?

public static ArrayList<Car> getCarsByFuelType(ArrayList cars, String fuelType)

然後,當你已經被過濾的集合,那麼你可以做你想和他們(即打印出來)是什麼?

下面是我如何實現它。我有一個CarCollection類,它包裝並提供您在私人ArrayList之上所需的訪問方法。喜歡這個。汽車的

public class CarCollection { 
    private ArrayList<Car> carList; 

    public void add(Car car) { 
     carList.add(car); 
    } 

    public CarCollection getCleanCars() { 
     CarCollection cleanCars = new CarCollection(); 
     for (Car car : this.cars) { 
      if (car.isClean()) { 
       cleanCars.add(car); 
      } 
     } 
     return cleanCars; 
    } 

    public CarCollection getCarsByFuelType(String fuelType) { 
     CarCollection filteredCars = new CarCollection(); 
     for (Car car : this.cars) { 
      if (car instanceof FuelCar) { 
       if (car.fuelType.equals(fuelType)) { 
        filteredCars.add(car); 
       } 
      } 
     } 
     return filteredCars; 
    } 
} 
0

硬編碼過濾列表:

public static List<Car> filterCleanFuelCars(List<Car> cars) { 
    List<Car> filtered = new LinkedList<>(); 
    for (Car c : cars) { 
     if (c instanceof FuelCar) { 
      FuelCar fuelCar = (FuelCar) c; 
      if (fuelCar.isClean()) { 
       filtered.add(fuelCar); 
      } 
     } 
    } 
    return filtered; 
} 

濾波基於自定義條件汽車的列表(硬編碼條件由謂詞替換):

public static List<Car> filterCars(List<Car> cars, Predicate<Car> condition) { 
    List<Car> filtered = new LinkedList<>(); 
    for (Car c : cars) { 
     if (condition.apply(c)) { 
      filtered.add(c); 
     } 
    } 
    return filtered; 
} 

相同如上Stream

public static List<Car> filterCars(List<Car> cars, Predicate<Car> condition) { 
    return cars.stream() 
       .filter(condition) 
       .collect(Collectors.toList()); 
} 
使用的

示例:

List<Car> cleanCars = filterCars(cars, new Predicate<Car>() { 
    @Override 
    public boolean apply(Car c) { 
     return c.isClean(); 
    } 
}); 

這可以通過lambda表達式(取代匿名類)被縮短

List<Car> cleanCars = filterCars(cars, (Car c) -> c.isClean()); 

如果需要更多的線,以決定該過濾器是否適用於汽車,你可以這樣寫:

List<Car> cleanFuelCars = filterCars(cars, (Car c) -> { 
    if (c instanceof FuelCar) { 
     FuelCar fuelCar = (FuelCar) c; 
     return c.isClean(); 
    } 
    return false; 
}); 

由於包含在列表中的汽車並非全部都是FuelCar,首先需要檢查車輛是否是FuelCar的實例,之後需要將該車投入FuelCar型,最後檢查fuelType屬性的值。

。注意,String值不能被使用==操作者檢查是否相等,因爲String不是原始數據類型int, long, float, double它們總是由值(當你通過int一種方法,然後int傳遞被複制到方法的局部變量 - 參數中)。通過==比較像String這樣的對象只檢查引用的相等性,即檢查兩個對象是否指向內存中的同一對象 - 對象始終是引用(地址)傳遞的。總之,當你使用字符串時總是使用equals方法。

public static void printCarsSpecific(List<Car> cars, String fuelType) { 
    for (Car c : cars) { 
     if (c instanceof FuelCar) { 
      FuelCar fuelCar = (FuelCar) c; 
      if (fuelCar.fuelType.equals(fuelType)) { 
       System.out.println(fuelCar); 
      } 
     } 
    } 
} 

您也可以重寫printCarsSpecific更通用的方法,通過使用filterCars方法:

public static void printCarsSpecific(List<Car> cars, Predicate<Car> p) { 
    List<Car> filtered = filterCars(cars, p); 
    for (Car c : filtered) { 
     System.out.println(c); 
    } 
} 

要打印汽油燃料的汽車,你可以這樣寫:

printCarsSpecific(cars, (Car c) -> { 
    if (c instanceof FuelCar) { 
     FuelCar fuelCar = (FuelCar) c; 
     retur fuelCar.fuelType.equals("gasoline"); 
    } 
    return false; 
}); 
0

如果您使用的是Java 8你可以使用花哨的流,如:

List<Car> cleanCars = carList.stream().filter(car -> car.isClean()).collect(Collectors.toList()); 

List<Car> carsFilteredOnFuelType = carList.stream().filter(car -> fueltype.equals(car.fueltype)).collect(Collectors.toList)); 
0

如果您不需要,我建議您不要將變量聲明爲ArrayList。抽象越大,代碼越一般,因此程序越強大。請看下面的例子:

ArrayList<Car> cars = new ArrayList<>(); 

爲什麼你不得不說,carsArrayList?您只需在實例化時指定確切的類型。這是優越:

AbstractList<Car> cars = new ArrayList<Car>(); 

ArrayListimplementsAbstractList,你可能會決定稍後切換到cars另一種類型的AbstractList實施。

此外,閱讀/觀看一些教程,因爲即使使用最基本的語法,您也在苦苦掙扎。

現在讓我們看看你的問題。你的第一個問題要求一種只列出清潔cars的方法。這個任務不是原子的,你需要分離任務。首先,獲得cars的乾淨子集是很好的。即使您不打算列出它們,這種類型的任務也可能很有用。因此,讓我們獨立實施:

public static AbstractList<Car> getCleanCars(AbstractList<Car> cars) { 
    AbstractList<Car> cleanCars = new ArrayList<Car>(); 
    for (Car car : cars) { 
     if (car.isClean()) { 
      cleanCars.add(car); 
     } 
    } 
    return cleanCars; 
} 

然後您需要一種顯示cars的方法。讓我們假設它看起來像這樣:

public static void displayCars(AbstractList<Car> cars) { 
    //Display the cars 
} 

您需要調用displayCars這樣的:Car.displayCars(Car.getCleanCars(cars))

你的第二個問題是不合邏輯的,因爲你要調用使用單個參數的兩個參數中聲明的方法。由於你的代碼充滿了錯誤,所以它真的無法讀取,所以我無法爲你提供幫助,但是,如果某種燃料類型可以從Car對象中確定,那麼您需要按照圖示反覆顯示汽車列表而不是調用isClean,則需要使用.equals()方法將Car的燃料類型作爲String與接收的參數進行比較。