将CSV文件中的数据导入自定义收集器

问题描述 投票:2回答:1

我试图从CSV文件中获取Car数据并将该数据收集到Custom Collector中,该收集器将返回List<Car>

Car.csv

CAR_NAME,CAR_MODEL,CAR_PRICE,CAR_MILEAGE,CAR_DETAILS
Jeep,Cherokee,45000,14000,Petrol
Nissan,Juke,10000,20000,Diesel
BMW,1 Series,9600,29000,Petrol
Mercedes,A Class,15000,40000,Petrol
BMW,5 Series,15000,7500,Petrol
Mercedes,C 220,23000,2000,Petrol
Mercedes,GLE,65000,40000,Diesel
Land Rover,Discovery Sport,15000,46000,Diesel
BMW,4 Series,25000,66000,Diesel
Nissan,Qashqai,4000,200000,Diesel
Toyota,Yaris,7500,12000,Hybrid
Ford,Mondeo,6500,47000,Diesel
Mercedes,B Class,8700,80000,Diesel
Ford,Mustang,68000,84000,Petrol
Peugeot,307cc,4500,58000,Diesel
Nissan,Almera,2000,48000,Petrol
Peugeot,207cc,6000,32000,Petrol
Fiat,Punto,500,223000,Petrol
Seat,Ibiza,990,78000,Diesel
BMW,8 Series,54000,45000,Hybrid
Range Rover,Evoque,25000,34000,Diesel
Ford,Focus,34000,126000,Diesel

我的车POJO

import java.util.List;
import java.util.Objects;

public class Car {

    private String name;
    private String model;
    private String price;
    private String mileage;
    private List<String> carDetails;

    public Car(String name, String model, String price, String mileage) {
        super();
        this.name = name;
        this.model = model;
        this.price = price;
        this.mileage = mileage;
    }

    public Car(String name, String model, String price, String mileage, List<String> carDetails) {
        super();
        this.name = name;
        this.model = model;
        this.price = price;
        this.mileage = mileage;
        this.carDetails = carDetails;
    }

    public String getName() {
        return name;
    }

    public String getModel() {
        return model;
    }

    public String getPrice() {
        return price;
    }

    public String getMileage() {
        return mileage;
    }

    public List<String> getCarDetails() {
        return carDetails;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Car)) return false;
        Car car = (Car) o;
        return Objects.equals(name, car.name) &&
                Objects.equals(model, car.model) &&
                Objects.equals(price, car.price) &&
                Objects.equals(mileage, car.mileage) &&
                Objects.equals(carDetails, car.carDetails);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, model, price, mileage, carDetails);
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", model='" + model + '\'' +
                ", price='" + price + '\'' +
                ", mileage='" + mileage + '\'' +
                ", carDetails=" + carDetails +
                '}';
    }
}

我的主要课程

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

public class StreamDeepDive {

    public static void main(String[] args) throws IOException {
        System.out.println(getData());
    }

    private static List<Car> getData() throws IOException {
        String filePath = "src/main/resources/cars.csv";
        List<Car> cars =  Files.lines(Paths.get(filePath)).skip(1).collect(toCarCollector()); // error is here
        return cars;
    }

    public static CarCollector toCarCollector(){
        return new CarCollector();
    }

    /**
     * My Custom Collector
     */
    private static class CarCollector implements Collector<Car, List<Car>, List<Car>> {

        @Override
        public Supplier<List<Car>> supplier() {
            return ArrayList::new;
        }

        @Override
        public BiConsumer<List<Car>, Car> accumulator() {
            return (List<Car> list, Car car) -> list.add(car);
        }

        @Override
        public BinaryOperator<List<Car>> combiner() {
            return (list1, list2) -> {
                list1.addAll(list2);
                return list1;
            };
        }

        @Override
        public Function<List<Car>, List<Car>> finisher() {
            return Function.identity();
        }

        @Override
        public Set<Characteristics> characteristics() {
            return null;
        }
    }
}

但是,当我尝试运行它时,我得到的错误是:reason: no instance(s) of type variable(s) exist so that String conforms to Car。我试图在网上寻找资源,试着看看如何将String转换为Car中的自定义类型即BiConsumer,但事实证明这对我来说是一个挑战。

java collections java-8 java-stream
1个回答
3
投票

一些观察:

  1. 您不需要自定义收集器,使用Collectors.toList()应该可以开箱即用。
  2. 你永远不会从每一行创建你的Car对象。我会使用Stream.map操作,要么在其构造函数中接收整行(所以我可以使用Car::new作为映射器函数),或者接收每个需要的字段,我在每次使用逗号后使用String.split线。
  3. 此外,您应该使用try-with-resources构造,以便正确关闭流和底层InputStream
© www.soinside.com 2019 - 2024. All rights reserved.