读取两个.text文件以匹配Java中的数据

时间:2014-05-13 02:08:21

标签: java eclipse

我正在研究一个学校项目,而我应该在两个不同的.txt文件中阅读。从文件我应该使用数据来分析它。并打印出一些分析的信息。具体来说,我有一个.txt文件,其中包含用户ID号和名字的列表。它看起来像这样:

1,Bobby
2,Joe
3,Sue
4,Mary
5,Victor

从那里我有另一个保存数据的.txt文件。它看起来像这样:

1,452,2127
2,500,1482
2,462,2490
3,172,2706

第一个数字是链接到另一个文件的客户ID,第二个是min的数量,第三个是文本消息的数量。

 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.Scanner;

 public class CustomerDriver2 {

public static void main(String[] args) throws FileNotFoundException {

    File custFile = new File("Customers.txt");
    Scanner custScanner = new Scanner(custFile);

    File usageFile = new File("CellPhoneUsage.txt");
    Scanner usageScanner = new Scanner(usageFile);

    int custID = 0;
    int custID2 = 0;
    String name = "";

    Customer myCustomer = new Customer(0, "");

    while(custScanner.hasNextLine())
    {
        String myLine = custScanner.nextLine();

        Scanner myLineScan = new Scanner(myLine);
        myLineScan.useDelimiter(",");   

        while(myLineScan.hasNext())
        {
            custID = myLineScan.nextInt();
            name = myLineScan.nextLine();

            myCustomer = new Customer(custID, name);

            while(usageScanner.hasNextLine())
            {

                String myLine2 = usageScanner.nextLine();
                Scanner myLineScan2 = new Scanner(myLine2);
                myLineScan2.useDelimiter(",");

                while (myLineScan2.hasNext())
                {
                    custID2 = myLineScan2.nextInt();
                    int calls = myLineScan2.nextInt();
                    int txt = myLineScan2.nextInt();

                    if(custID == custID2)
                    {
                        myCustomer.setMinTotal(calls);
                        myCustomer.setTxtTotal(txt);
                    }

                }

            }
            System.out.println(myCustomer.toString());
        }

    }

}//end of main

} //班级的结尾

根据我目前的情况,我得到这样的输出:

Name: ,Bobby
Min Sum: 3509
Text Sum: 21370
Min Average: 350
Txt Average: 2137

Name: ,Joe
Min Sum: 0
Text Sum: 0
Min Average: 0
Txt Average: 0

Name: ,Sue
Min Sum: 0
Text Sum: 0
Min Average: 0
Txt Average: 0

Name: ,Mary
Min Sum: 0
Text Sum: 0
Min Average: 0
Txt Average: 0

Name: ,Victor
Min Sum: 0
Text Sum: 0
Min Average: 0
Txt Average: 0

这是正确的名称,但它没有正确获取数据。我对自己哪里出错感到困惑。

我需要的是其他4个名称也具有第一个名称的数据类型。

我还有另一个名为Customer的类进行计算:

 public class Customer {

int custID;
String name;

int totalMin;
int totalTxt;

//constructor
public Customer(int custID, String name)
{
    this.custID = custID;
    this.name = name;
}

public Customer(int custID, int totalMin, int totalTxt)
{
    this.custID = custID;
    this.totalMin = totalMin;
    this.totalTxt = totalTxt;
}

public void setMinTotal(int min)
{
    this.totalMin = totalMin + min;
}
public void setTxtTotal(int txt)
{
    this.totalTxt = totalTxt + txt;
}

public int getAvgMin()
{
    return totalMin/10;
}
public int getAvgTxt()
{
    return totalTxt/10;
}

public String toString()
{
    return "Name: " + name + "\n"
            + "Min Sum: " + totalMin +"\n"
            + "Text Sum: "+ totalTxt + "\n"
            + "Min Average: " + getAvgMin() + "\n"
            + "Txt Average: " + getAvgTxt()+ "\n";
}
}

3 个答案:

答案 0 :(得分:1)

我认为你的问题是

 while(usageScanner.hasNextLine())
            {

                String myLine2 = usageScanner.nextLine();
.....

完全遍历这些行后(第一个客户会发生这种情况),这将始终返回false。

你必须重写一些代码来解决它。

你可以 1.在每个循环上实例化一个新的扫描程序(资源非常昂贵)2。分别解析该文件并将客户ID和数据存储在单独的对象列表中,而不是当迭代客户从该列表中提取数据时

修改

这是我的解决方案1(快速实施但资源昂贵)。您必须在第一个循环内实例化每次扫描的新用法

更改

File usageFile = new File("CellPhoneUsage.txt");
//Scanner usageScanner = new Scanner(usageFile);
...
while(custScanner.hasNextLine())
    {
    Scanner usageScanner = new Scanner(usageFile);

答案 1 :(得分:0)

您的问题是,在您的第一个while(myLineScan.hasNext())循环中,您将多次重新分配变量,然后只使用第一个值。基本上,它看起来像这样:

Initially, custID=0 and name=""
Enter loop
    read line, going with your provided input, custID is now 1 and name is "Bobby"
    Loop again, read next line. custID is now 2 and name is "Joe"
    **** this is where you lose your data; the original id 1 and name "Bobby" are now lost and won't be processed
    Repeat for all names, throwing them all out
You are left with just the last line's custID and name
Your code goes on to parse only that data

看看问题是什么?您需要管理在第一个循环中解析的所有数据,而不是将其丢弃。我建议您使用HashMap将客户ID与名称相关联。所以在你的第一个循环中执行类似

的操作
Map<Integer, String> idsToNames=new HashMap<>(); // create a map of ids to names
while(myLineScan.hasNext()) {
    int theId = myLineScan.nextInt();
    String theName = myLineScan.nextLine();
    idsToNames.put(theId, theName);
}//end while loop

// Then later retrieve data based on id like this:
int idYouWantToFind=//whatever
String nameCorrespondingToThatId=idsToNames.get(idYouWantToFind);

请注意,在HashMaps和其他泛型类中,您需要将Integer指定为泛型参数,而不是int。 Float,Char,Byte和所有其他原语也是如此。 Java将自动负责将整数转换为整数等。更多信息请访问:http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#instantiate

答案 2 :(得分:0)

晚会,但这是避免过度使用扫描仪的解决方案。

public static void main(String[] args) throws FileNotFoundException {

    File custFile = new File("Customers.txt");
    Scanner custScanner = new Scanner(custFile);

    File usageFile = new File("CellPhoneUsage.txt");
    Scanner usageScanner = new Scanner(usageFile);

    ArrayList<Customer> customers = new ArrayList<Customer>();
    ArrayList<Usage> usages = new ArrayList<Usage>();

    //begins customer scanning
    while (custScanner.hasNextLine()) {
        String myLine = custScanner.nextLine();

        Scanner myLineScan = new Scanner(myLine);
        myLineScan.useDelimiter(",");

        while (myLineScan.hasNext()) {
            int custID = myLineScan.nextInt();
            String name = myLineScan.nextLine();
            customers.add(new Customer(custID, name));
        }
    }

    //begins usage scanning
    while (usageScanner.hasNextLine()) {
        String myLine2 = usageScanner.nextLine();

        Scanner myLineScan2 = new Scanner(myLine2);
        myLineScan2.useDelimiter(",");

        while (myLineScan2.hasNext()) {
            int custID = myLineScan2.nextInt();
            int calls = myLineScan2.nextInt();
            int txt = myLineScan2.nextInt();
            usages.add((new Usage(custID, calls, txt)));
        }
    }

    for (Customer customer : customers) {
        // Iterator to remove matching usage data while iterating 
        // (more efficient in that it avoids needlessly looping over
        // usages that have already been applied)
        Iterator<Usage> i = usages.iterator();
        while (i.hasNext()) {
            Usage usage = i.next();
            if (usage.custID == customer.custID) {
                customer.setMinTotal(usage.calls);
                customer.setTxtTotal(usage.txts);
                i.remove();
            }
        }
        System.out.println(customer.toString());
    }
}

简单用法类:

class Usage {
    int custID;
    int calls;
    int txts;

    Usage(int custID, int calls, int txts) {
        this.custID = custID;
        this.calls = calls;
        this.txts = txts;
    }
}