Java方法读取文本文件并返回ArrayList类型对象

huangapple go评论74阅读模式
英文:

Java method to read text file and return ArrayList type object

问题

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>”。

如何修复这个问题?

英文:
    public static void main(String[] args)
{
ArrayList &lt;Locations&gt;       LocationsList       = readFile(&quot;Locations.csv&quot;, &quot;Locations&quot;);
//ArrayList &lt;Movies&gt;          MoviesList          = readFile(&quot;Movies.csv&quot;, &quot;Movies&quot;);
//ArrayList &lt;Operators&gt;       OperatorsList       = readFile(&quot;Operators.csv&quot;, &quot;Operators&quot;);
//ArrayList &lt;PersonCategory&gt;  PersonCategoryList  = readFile(&quot;PersonCategory.csv&quot;, &quot;PersonCategory&quot;);
}
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,&quot;,&quot;);
if(line != 0)
{
if(whichFile.equals(&quot;Locations&quot;))
{
int id = Integer.parseInt(st.nextToken());
String city = st.nextToken();
if(city.charAt(0) == &#39;&quot;&#39;)
{
String c = st.nextToken();
city = city.substring(1,city.length()) +&quot;,&quot; +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(&quot;Movies&quot;))
{
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;
}

I'm trying to create a method that will read a text file and can return an ArrayList type object for the usage of multiple Class. With my code above, it can run successfully.

But, there are lines of warning like:
"The expression of type ArrayList needs unchecked conversion to conform to ArrayList&lt;Locations&gt;"

How do I fix this?

答案1

得分: 1

请尝试以下代码:

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) {
    /* 从字段创建Movies对象 */
}

并将它们组合起来

ArrayList<Locations> LocationsList = readFile("Locations.csv", fields -> convertLocations(fields));
ArrayList<Movies> MoviesList = readFile("Movies.csv", fields -> convertMovies(fields));
英文:

Try this.

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

and define the converters which convert a CSV line to an object.

static Locations convertLocations(String[] fields) {
int id = Integer.parseInt(fields[0]);
String city = fields[1];
if (city.charAt(0) == &#39;&quot;&#39;) {
String c = fields[2];
city = city.substring(1, city.length()) + &quot;,&quot; + 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 */
}

and combine them.

ArrayList&lt;Locations&gt; LocationsList = readFile(&quot;Locations.csv&quot;, fields -&gt; convertLocations(fields));
ArrayList&lt;Movies&gt; MoviesList = readFile(&quot;Movies.csv&quot;, fields -&gt; convertMovies(fields));

答案2

得分: 0

你需要使用泛型创建正确的ArrayList,例如:new ArrayList<Location>()

你可以通过像这样将一个类传递给readFile来解决这个问题:

public static <T> ArrayList<T> readFile(....., Class<T> clazz)
{
   ArrayList<T> list = new ArrayList<T>();
   ...
}
英文:

You need to create the proper generics-based ArrayList using for example: new ArrayList&lt;Location&gt;()

You could solve this by passing a class to readFile like this:

public static &lt;T&gt; ArrayList&lt;T&gt; readFile(....., Class&lt;T&gt; clazz)
{
ArrayList&lt;T&gt; list = new ArrayList&lt;T&gt;();
...
}

答案3

得分: 0

Essentially, you need to specify the type parameter for generic 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;
  1. 或者,您可以为每个具体类型编写一个列表转换函数
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 或任何与领域相关的名称。

英文:

Essentially, you need to specify the type parameter for generic class ArrayList.

Since you are adding objects created from different classes to the same list, you could create an interface, say, MyInterface

public interface MyInterface {
    ....
}

All classes you return from readFile must implement this interface. For eg.

public class Movies implements MyInterface {
    ....
}

Now, you can add type parameter MyInterface at appropriate places:

public static void main(String[] args) {
        ArrayList&lt;MyInterface&gt; LocationsList = readFile(&quot;Locations.csv&quot;, &quot;Locations&quot;);
        ....
    }

public static ArrayList&lt;MyInterface&gt; readFile(String fileName, String whichFile) {
 
  ArrayList&lt;MyInterface&gt; list = new ArrayList&lt;&gt;();
            ....
        }

Added below info based on reply

You may in fact choose to leave the interface blank, but then you will have to explicitly cast objects to concrete classes to do anything useful.

  1. You could cast each object when needed
	    MyInterface myInterfaceObject = locationsList.get(0)
Locations locations = Locations.class.cast(myInterfaceObject);

OR

	    MyInterface myInterfaceObject = locationsList.get(0)
Locations locations = (Locations) myInterfaceObject;
  1. OR You could write a list converter function for each concrete type
public class ListConverter {
public ArrayList&lt;Locations&gt; toLocationsArraylist(ArrayList&lt;MyInterface&gt; inList) {
ArrayList&lt;Locations&gt; outList = new ArrayList&lt;&gt;();
for (MyInterface listItem : inList) {
outList.add((Locations) listItem);
}
return outList;
}
}

and then

public static void main(String[] args) {
ArrayList&lt;MyInterface&gt; myInterfaceList = readFile(&quot;Locations.csv&quot;, &quot;Locations&quot;);
ArrayList&lt;Locations&gt; locationList = ListConverter.toLocationsArraylist(myInterfaceList);
}

If you do consider using this solution, then consider renaming MyInterface more appropriately, say, to CsvRecord, or anything domain-specific.

答案4

得分: 0

这是我从@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;
}

这是我对@saka1029答案中convertLocations方法的修正版本。

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;
}
英文:

This is my final code that I took from @saka1029 and made some adjustments so that it will read every line in the file except the first one.

    public static &lt;T&gt; ArrayList&lt;T&gt; readFile(String fileName, Function&lt;String[], T&gt; converter)
{
ArrayList &lt;T&gt; list = new ArrayList&lt;&gt;();
try
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine();
String inData;
while((inData=br.readLine()) != null)
{
String[] fields = inData.split(&quot;,&quot;);
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;
}

And this is my version of the correction of the method convertLocations from @saka1029 answer.

    static Locations convertLocations(String[] fields)
{
int id = Integer.parseInt(fields[0]);
String city = fields[1];
int stateId;
if (city.charAt(0) == &#39;&quot;&#39;)
{
String c = fields[2];
city = city.substring(1, city.length()) + &quot;,&quot; + 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;
}

huangapple
  • 本文由 发表于 2020年8月7日 15:13:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63296954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定