Java метод чтения текстового файла и возврата объекта типа ArrayList - PullRequest
1 голос
/ 07 августа 2020
    public static void main(String[] args)
    {
        ArrayList <Locations>       LocationsList       = readFile("Locations.csv", "Locations");
        //ArrayList <Movies>          MoviesList          = readFile("Movies.csv", "Movies");
        //ArrayList <Operators>       OperatorsList       = readFile("Operators.csv", "Operators");
        //ArrayList <PersonCategory>  PersonCategoryList  = readFile("PersonCategory.csv", "PersonCategory");
    }
    
    public static ArrayList readFile(String fileName, String whichFile)
    {
        ArrayList list = new ArrayList();

        try
        {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            
            String indata;
            
            int line = 0;
            while((indata=br.readLine())!=null)
            {
                StringTokenizer st = new StringTokenizer(indata,",");
                
                if(line != 0)
                {
                    if(whichFile.equals("Locations"))
                    {
                        int id = Integer.parseInt(st.nextToken());
                        String city = st.nextToken();
                        if(city.charAt(0) == '"')
                        {
                            String c = st.nextToken();
                            city = city.substring(1,city.length()) +"," +c.substring(0,c.length()-1);
                        }
                        int stateId = Integer.parseInt(st.nextToken());
                        
                        Locations x = new Locations(id, city, stateId);
                        list.add(x);
                    }
                    
                    else if(whichFile.equals("Movies"))
                    {
                        int id = Integer.parseInt(st.nextToken());
                        String name = st.nextToken();
                        int ratingId = Integer.parseInt(st.nextToken());
                        
                        Movies x = new Movies(id, name, ratingId);
                        list.add(x);
                    }                              
                }
                
                line++;
            }
            
            br.close();
        }
        catch (FileNotFoundException fnfe){System.out.println(fnfe.getMessage());}
        catch (IOException io){System.out.println(io.getMessage());}
        catch (Exception e){System.out.println(e.getMessage());}
        
        return list;
    }

Я пытаюсь создать метод, который будет читать текстовый файл и может возвращать объект типа ArrayList для использования нескольких классов. С моим приведенным выше кодом он может работать успешно.

Но есть строки с предупреждениями, например: «Выражение типа ArrayList требует неконтролируемого преобразования, чтобы соответствовать ArrayList<Locations>»

Как мне исправить это?

Ответы [ 4 ]

1 голос
/ 07 августа 2020

Попробуйте это.

public static <T> ArrayList<T> readFile(String fileName, Function<String[], T> converter) throws IOException {
    ArrayList<T> result = new ArrayList<>();
    try (BufferedReader reader = Files.newBufferedReader(Paths.get(fileName))) {
        String line = reader.readLine();
        String[] fields = line.split(",");
        T object = converter.apply(fields);
        result.add(object);
    }
    return result;
}

и определите преобразователи, которые преобразуют строку CSV в объект.

static Locations convertLocations(String[] fields) {
    int id = Integer.parseInt(fields[0]);
    String city = fields[1];
    if (city.charAt(0) == '"') {
        String c = fields[2];
        city = city.substring(1, city.length()) + "," + c.substring(0, c.length() - 1);
    }
    int stateId = Integer.parseInt(fields[3]);
    Locations x = new Locations(id, city, stateId);
    return x;
}

static Movies convertMovies(String[] fields) {
    /* Make Movies object from fields */
}

и объединят их.

ArrayList<Locations> LocationsList = readFile("Locations.csv", fields -> convertLocations(fields));
ArrayList<Movies> MoviesList = readFile("Movies.csv", fields -> convertMovies(fields));
0 голосов
/ 08 августа 2020

Это мой последний код, который я взял из @ saka1029 и внес некоторые изменения, чтобы он читал каждую строку в файле, кроме первой.

    public static <T> ArrayList<T> readFile(String fileName, Function<String[], T> converter)
    {
        ArrayList <T> list = new ArrayList<>();

        try
        {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            br.readLine();
            
            String inData;
            
            while((inData=br.readLine()) != null)
            {
                String[] fields = inData.split(",");
                T object = converter.apply(fields);
                list.add(object);
            }
            
            br.close();
        }
        catch (FileNotFoundException fnfe){System.out.println(fnfe.getMessage());}
        catch (IOException io){System.out.println(io.getMessage());}
        catch (Exception e){System.out.println(e.getMessage());}
        
        return list;
    }

И это моя версия исправления метода convertLocations из ответа @ saka1029.

    static Locations convertLocations(String[] fields)
    {
        int id = Integer.parseInt(fields[0]);
        String city = fields[1];
        int stateId;
        if (city.charAt(0) == '"')
        {
            String c = fields[2];
            city = city.substring(1, city.length()) + "," + c.substring(0, c.length() - 1);
            stateId = Integer.parseInt(fields[3]);
        }
        else
            stateId = Integer.parseInt(fields[2]);
        
        Locations x = new Locations(id, city, stateId);
        
        return x;
    }
0 голосов
/ 07 августа 2020

По сути, вам необходимо указать параметр типа для generi c class ArrayList.

Поскольку вы добавляете объекты, созданные из разных классов, в один и тот же список, вы можете создать интерфейс, скажем, MyInterface

public interface MyInterface {
    ....
}

Все классы, возвращаемые из readFile, должны реализовывать этот интерфейс. Например,

public class Movies implements MyInterface {
    ....
}

Теперь вы можете добавить параметр типа MyInterface в соответствующие места:

public static void main(String[] args) {
        ArrayList<MyInterface> LocationsList = readFile("Locations.csv", "Locations");
        ....
    }

public static ArrayList<MyInterface> readFile(String fileName, String whichFile) {
 
  ArrayList<MyInterface> list = new ArrayList<>();
            ....
        }

Информация ниже добавлена ​​на основе ответа

Фактически вы можете оставить интерфейс пустым, но тогда вам придется явно приводить объекты к конкретным классам, чтобы делать что-нибудь полезное.

  1. Вы можете преобразовать каждый объект, когда это необходимо
        MyInterface myInterfaceObject = locationsList.get(0)
        Locations locations = Locations.class.cast(myInterfaceObject);

ИЛИ

        MyInterface myInterfaceObject = locationsList.get(0)
        Locations locations = (Locations) myInterfaceObject;
ИЛИ Вы можете написать функцию конвертера списков для каждого конкретного типа
public class ListConverter {
  public ArrayList<Locations> toLocationsArraylist(ArrayList<MyInterface> inList) {
      ArrayList<Locations> outList = new ArrayList<>();
      for (MyInterface listItem : inList) {
          outList.add((Locations) listItem);
      }
      return outList;
  }
}

, а затем

public static void main(String[] args) {
        ArrayList<MyInterface> myInterfaceList = readFile("Locations.csv", "Locations");
        ArrayList<Locations> locationList = ListConverter.toLocationsArraylist(myInterfaceList);
       
    }

Если вы все же решите использовать это решение, рассмотрите возможность переименования MyInterface. более уместно, скажем, CsvRecord или что-нибудь, специфичное для домена c.

0 голосов
/ 07 августа 2020

Вам необходимо создать правильный ArrayList на основе обобщений, например, используя: new ArrayList<Location>()

Вы можете решить эту проблему, передав класс readFile следующим образом:

public static <T> ArrayList<T> readFile(....., Class<T> clazz)
{
   ArrayList<T> list = new ArrayList<T>();
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...