美好的一天,
想象一下,我有以下代码: (这些显然不是所有属性)
ArrayList
将对象添加到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<Car> cars = new ArrayList<>();
现在的问题是:
我如何制作一个方法,所以我只列出所有价值为isClean“true”的汽车;
如何使用以下签名创建方法: public static void printCarsSpecific(ArrayList Cars,String fuelType) 所以,例如,如果我投入: printCarsSpecific( “汽油”); 打印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")));
和
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));
}
}
}
我想我不必删除这些项目,就像我在这里看到的例子一样。
答案 0 :(得分: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;
}
}
答案 1 :(得分: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;
});
答案 2 :(得分: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));
答案 3 :(得分:0)
如果您不需要,我建议您不要将变量声明为ArrayList
。抽象越大,代码就越通用,因此程序就越强大。看看这个例子:
ArrayList<Car> cars = new ArrayList<>();
为什么你要说cars
为ArrayList
?您只需在实例化时指定确切的类型。这是优越的:
AbstractList<Car> cars = new ArrayList<Car>();
ArrayList
implements
AbstractList
您可能稍后决定将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
,您需要使用{{1}将Car
的燃料类型与String
进行比较。方法。