简体   繁体   English

从键盘(1 个值参数)或从文件(0 个值参数)读取的方法在 0 参数下无法正常工作

[英]Method that reads from keyboard(1 value parameter) or from a file(0 value parameter) doesn't work properly at 0 parameter

I want my method to read triangles from keyboard or from file and then be added to ArrayList .. I have 2 classes: Point defined by 2 coordinates: int c1,int c2 , and Triangle class defined by a color string and 3 points.我希望我的方法从键盘或文件中读取三角形,然后将其添加到ArrayList .. 我有 2 个类:由 2 个坐标定义的点: int c1,int c2和由颜色字符串和 3 个点定义的 Triangle 类。 I have 2 methods, one in Triangle class and one in Point class:我有两种方法,一种在Triangle类中,一种在Point类中:

Triangle class method:三角形类方法:

public Triangle readingTriangle(int value) throws Exception {
        if(value == 1) {
        Scanner sc = new Scanner(System.in);
        Triangle reserve =new Triangle();
        reserve.color = sc.next();
        reserve.setA(reserve.A.readingPoint(1));
        reserve.setB(reserve.B.readingPoint(1));
        reserve.setC(reserve.C.readingPoint(1));
        return reserve;
        }
        if(value == 0) {
            Scanner input = new Scanner(new File("File"));
            Triangle reserve1 =new Triangle();

            reserve1.color=input.next();
            reserve1.setA(reserve1.A.readingPoint(0));
            reserve1.setB(reserve1.B.readingPoint(0));
            reserve1.setC(reserve1.C.readingPoint(0));
            return reserve1;
        }
        return new Triangle();


    }

Point class method:点类方法:

public Point readingPoint(int value) throws Exception {
        if(value==1) {
        Scanner sc = new Scanner(System.in);
        Point reserve=new Point();
        reserve.c1 = sc.nextInt();
        reserve.c2 = sc.nextInt();
        return reserve;
        }
        if(value==0) {
            Point reserve1=new Point();
            Scanner input1 = new Scanner(new File("File"));

            input1.next();
            reserve1.c1=input1.nextInt();
            reserve1.c2=input1.nextInt();


            return reserve1;

        }
        return new Point();

    }

In test class:在测试类中:

    Scanner sc = new Scanner(System.in);
    int triangleNumber = sc.nextInt();
    List<Triangle> triangleList = new ArrayList<Triangle>();

    for (int i = 0; i < triangleNumber; i++) {
        Triangle t = new Triangle();
        Triangle t1 = t.readingTriangle(0);
        triangleList.add(t1);

    }
    System.out.println(triangleList);

My output:我的输出:

[Triangle [color=green, A=Point [c1=20, c2=20], B=Point [c1=20, c2=20], C=Point [c1=20, c2=20]]]

My File:我的文件:

green
20 20
40 40
60 60

First, I want to mention that first piece of method is working (1 value parameter is working), I have problems with reading from file.首先,我想提到第一条方法正在工作(1 个值参数正在工作),我在读取文件时遇到问题。 You can see the problem from output:"20 20" is given for B and C points.您可以从输出中看到问题:B 和 C 点给出了“20 20”。

I have some things that I try to respect:我试图尊重一些事情:

  • I want my structures of methods to be, if possible, respected;如果可能,我希望我的方法结构得到尊重;

  • Using Scanner is mandatory(I know it's old technique);必须使用 Scanner(我知道这是旧技术);

  • I don't want to change my file, because if it was a real notepad, I don't think I will stay to change things in notepad.我不想更改我的文件,因为如果它是一个真正的记事本,我认为我不会留下来更改记事本中的内容。

Other observations:其他观察:

I think the problem is at scanner methods, I tried with while( input1.hasNext() ).我认为问题出在扫描仪方法上,我尝试使用 while( input1.hasNext() )。

you have to use the same instance of Scanner .您必须使用相同的Scanner实例。 here you are creating a new instance in each iteration in the loop, so each time it will start from the beginning of the file.在这里,您将在循环中的每次迭代中创建一个新实例,因此每次都会从文件的开头开始。 So I suggest to create a single instance in main class and pass it as parameter in your methods.所以我建议在主类中创建一个实例并将它作为参数传递给你的方法。

Triangle class method:三角形类方法:

public Triangle readingTriangle(int value, Scanner sc,Scanner input) throws Exception {
    if(value == 1) {
    Triangle reserve =new Triangle();
    reserve.color = sc.next();
    reserve.setA(reserve.A.readingPoint(1,sc,input));
    reserve.setB(reserve.B.readingPoint(1,sc,input));
    reserve.setC(reserve.C.readingPoint(1,sc,input));
    return reserve;
    }
    if(value == 0) {
        Triangle reserve1 =new Triangle();

        reserve1.color=input.next();
        reserve1.setA(reserve1.A.readingPoint(0,sc,input));
        reserve1.setB(reserve1.B.readingPoint(0,sc,input));
        reserve1.setC(reserve1.C.readingPoint(0,sc,input));
        return reserve1;
    }
    return new Triangle();


}

Point class method:点类方法:

public Point readingPoint(int value, Scanner sc,Scanner input) throws Exception {
    if(value==1) {
    Point reserve=new Point();
    reserve.c1 = sc.nextInt();
    reserve.c2 = sc.nextInt();
    return reserve;
    }
    if(value==0) {
        Point reserve1=new Point();
        reserve1.c1=input.nextInt();
        reserve1.c2=input.nextInt();


        return reserve1;

    }
    return new Point();

}

In test class:在测试类中:

Scanner sc = new Scanner(System.in); //the only time you create new instance of Scanner(System.in) -> for keybord input
Scanner input = new Scanner(new File("File"));//the only time you create new instance of Scanner(new File("File")) -> for file input

int triangleNumber = sc.nextInt();
List<Triangle> triangleList = new ArrayList<Triangle>();
for (int i = 0; i < triangleNumber; i++) {
    Triangle t = new Triangle();
    Triangle t1 = t.readingTriangle(0,sc,input);
    triangleList.add(t1);

}
System.out.println(triangleList);

But, if you insist to not change your parameters and keep the same structure of your actual code, you can use the method of singleton, which I do not recommend especially if you work with threads.但是,如果您坚持不更改参数并保持实际代码的相同结构,则可以使用单例方法,我不建议使用这种方法,尤其是在使用线程时。 It works fine if you're not using threads.如果您不使用线程,它可以正常工作。

So to use a single instance of Scanner (or any other datatype or class), you can use the design pattern "Singleton" which consist to instantiate a single instance of your Object for the whole project.因此,要使用Scanner的单个实例(或任何其他数据类型或类),您可以使用设计模式“Singleton”,它包括为整个项目实例化对象的单个实例。

The Singleton definition for input from keyboard (a new class) :键盘输入的单例定义(一个新类):

import java.util.Scanner;

public class ScannerSingletonKeyboard {
      private static Scanner sc = null;

    private ScannerSingletonKeyboard(){
        sc = new Scanner(System.in); 

    }

    public static Scanner getInstance(){
        if(sc==null)
             new ScannerSingletonKeyboard();
        return sc;

    }
}

The Singleton definition for input from the file (a new class) :来自文件的输入的单例定义(一个新类):

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

public class ScannerSingletonFile {
      private static Scanner sc = null;

    private ScannerSingletonFile(){
        try {
            Scanner sc = new Scanner(new File("File"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static Scanner getInstance(){
        if(sc==null)
             new ScannerSingletonFile();
        return sc;

    }
}

Triangle class method:三角形类方法:

public Triangle readingTriangle(int value) throws Exception {
    if(value == 1) {
        Scanner sc = ScannerSingletonKeyboard.getInstance();
        Triangle reserve =new Triangle();
        reserve.color = sc.next();
        reserve.setA(reserve.A.readingPoint(1));
        reserve.setB(reserve.B.readingPoint(1));
        reserve.setC(reserve.C.readingPoint(1));
        return reserve;
    }
    if(value == 0) {
        Triangle reserve1 =new Triangle();
        Scanner input = ScannerSingletonFile.getInstance();
        reserve1.color=input.next();
        reserve1.setA(reserve1.A.readingPoint(0));
        reserve1.setB(reserve1.B.readingPoint(0));
        reserve1.setC(reserve1.C.readingPoint(0));
        return reserve1;
    }
    return new Triangle();


}

Point class method:点类方法:

public Point readingPoint(int value) throws Exception {
    if(value==1) {
        Scanner sc = ScannerSingletonKeyboard.getInstance();
        Point reserve=new Point();
        reserve.c1 = sc.nextInt();
        reserve.c2 = sc.nextInt();
        return reserve;
    }
    if(value==0) {
        Scanner input = ScannerSingletonFile.getInstance();
        Point reserve1=new Point();
        input.next();
        reserve1.c1=input.nextInt();
        reserve1.c2=input.nextInt();


        return reserve1;

    }
    return new Point();

}

In test class:在测试类中:

Scanner sc = ScannerSingletonKeyboard.getInstance();


int triangleNumber = sc.nextInt();
List<Triangle> triangleList = new ArrayList<Triangle>();
for (int i = 0; i < triangleNumber; i++) {
    Triangle t = new Triangle();
    Triangle t1 = t.readingTriangle(0);
    triangleList.add(t1);

}
System.out.println(triangleList);

and each time you want to use your scanner anywhere you only have to call ScannerSingletonKeyboard.getInstance() for keyboard input or ScannerSingletonFile.getInstance() for file inout which will return your single instance of scanner每次您想在任何地方使用扫描仪时,您只需调用ScannerSingletonKeyboard.getInstance()进行键盘输入或调用ScannerSingletonFile.getInstance()进行文件输入,这将返回您的扫描仪的单个实例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM