01/10/2018, 01:09

Cách làm mã sinh viên tự động tăng trong Java

Đề bài yêu cầu đọc sinh viên từ file INPUT.txt và hiển thị thông tin sinh viên, sinh viên gồm tên và mã sv, file INPUT chỉ chứa tên sinh viên, còn mã sv thì tự động tăng, bắt đầu từ 1.
E chưa hiểu sao em làm mà nó bị sai chỗ mã sinh viên tự động tăng, và chưa biết sửa thế nào, mong m.n giúp
đây là class SinhVien

public class SinhVien {
    private static int maSV = 0;
    private String tenSV;

    public SinhVien() {
        maSV++;
    }
    
    public void nhap(Scanner sc){
        tenSV = sc.nextLine();
    }

    @Override
    public String toString() {
        return maSV + " " + tenSV + "
";
    }
    
}

đây là class Main

public class Main {
    
    public static void main(String[] args) throws FileNotFoundException {
        ArrayList<SinhVien> ds = new ArrayList<>();
        Scanner sc = new Scanner(new File("INPUT.txt"));
        while(sc.hasNextLine()){
            SinhVien sv = new SinhVien();
            sv.nhap(sc);
            ds.add(sv);
        }
        
        for(SinhVien sv: ds){
            System.out.println(sv.toString());
        }
    }
}

Nội dung file INPUT.txt
nguyen van a
nguyen van b
nguyen van c
nguyen van s
nguyen van d
nguyen van f
nguyen van g
nguyen van h
nguyen van j

kết quả nếu chạy đúng là:
1 nguyen van a
2 nguyen van b
3 nguyen van c
4 nguyen van s
5 nguyen van d
6 nguyen van f
7 nguyen van g
8 nguyen van h
9 nguyen van j

nhưng code trên thì nó lại ra thế này
9 nguyen van a
9 nguyen van b
9 nguyen van c
9 nguyen van s
9 nguyen van d
9 nguyen van f
9 nguyen van g
9 nguyen van h
9 nguyen van j

Ngô Doãn Tuấn viết 03:25 ngày 01/10/2018

private static int maSV = 0;

biến static bạn thử kiểm tra lại

Hidan viết 03:17 ngày 01/10/2018

các sinh viên đâu có cùng mã sinh viên mà thêm static, cùng trường thì được.

Tynk Huynk viết 03:15 ngày 01/10/2018

1 cách làm “thô thiển” của mình đề ra: tạo 1 biến int maSV trong hàm main, mỗi lầ lặp của vòng while thì maSV++ rồi gán giá trị của maSV cho biến instance của SinhVien tương ứng

Đỗ Trung Quân viết 03:12 ngày 01/10/2018

1: Em cần tạo 1 biến idTemp kiểu Static, khởi tạo lúc class được load tới khi chương trình kết thúc.
2: Mỗi lần khởi tạo mới id sẽ được tự động tăng theo idTemp

public class Person
{
  // arguments are passed using the text field below this editor
  public static void main(String[] args)
  {
    Student student = null;
    for(int i = 0 ; i<5; i++){
    	student = new Student("Do Quan ");
      	System.out.println(student.toString());
    }
  }
}

// you can add other public classes to this editor in any order
public class Student
{
  private static int idTemp = 1; // need a temp id
  private int id;
  private String name;
  
  Student(String name){ // each time we create new Student idTemp will be auto increas by 1
       this.id = idTemp++; // set id equal idTemp
       this.name = name;
  }
 	
  public String toString(){
       return "User: " + name + " " + id;
  }
}

Output:

User: Do Quan  1
User: Do Quan  2
User: Do Quan  3
User: Do Quan  4
User: Do Quan  5
Hoang Nguyen viết 03:25 ngày 01/10/2018

Để giải quyết vấn đề đó e nên làm như thế này. Lý do đáp án e in ra bị sai là vì mã sinh viên của mỗi instance SinhVien e sinh ra reference tới một static variable. Em đọc thêm về static variable, và từ khoá this trong Java nhé.

public class Student {
    private static int currentId = 0;
    private int id;
    private String name;

    public Student() {
        this.id = currentId++;
    }
    
    public void input(Scanner sc){
        this.name = sc.nextLine();
    }

    @Override
    public String toString() {
        return this.id + " " + this.name + "\n";
    }
}
bongtoi viết 03:20 ngày 01/10/2018

cảm ơn các bạn/anh rất nhiều @qtd @codeaholicguy @Tynk_Huynk @Hidan @TheSky

Duc viết 03:25 ngày 01/10/2018

Học lập trình quan trọng là hiểu logic. Hiểu cách máy tính suy nghĩ. Học cách giải quyết vấn đề. Và tất nhiên 1 vấn đề có nhiều lời giải. Những lời giải của các anh ở trên đúng và giải đáp được đề bài. Còn code của bạn… lí do mà bạn chạy ra số 9 ấy là vì dòng lệnh enhanced for loop để in array. Máy tính sẽ hiểu thế này

while(sc.hasNextLine()){
                SinhVien sv = new SinhVien();
                sv.nhap(sc);
                ds.add(sv);
            }

ds size=0 sv =1 nguyen van a (array list dùng size, array thì dùng ds[index])
ds size=1 sv =2 nguyen van a
ds size=2 sv =3 nguyen van b

ds size=8 sv =9 nguyen van j
ds size=9 sv=null (return null , end while loop)

Khi mà chạy dòng enhanced for loop in Array List

for (SinhVien sv : ds) {
            //for (int i = 0 ; i < ds.size() ; i++){
                System.out.println(sv.toString());
            }

**1st loop: ds size=9 sv=9 nguyen van a **
2nd loop: d size=9 sv=9 nguyen van b
3rd loop: ds size=9 sv=9 nguyen van c

9th loop: ds size=9 sv=9 nguyen van j

nếu bạn thay enhanced for loop bằng for loop thường:

        for (int i = 0 ; i < ds.size() ; i++){
            System.out.println(ds.toString());
        }

bạn sẽ in ra 9 cái array size có cùng 1 kết quả
**[**9 nguyen van a
, 9 nguyen van b
, 9 nguyen van c
, 9 nguyen van s
, 9 nguyen van d
, 9 nguyen van f
, 9 nguyen van g
, 9 nguyen van h
, 9 nguyen van j
]

tuannt viết 03:24 ngày 01/10/2018

Cảm ơn a @vietduc nhiều.

Duc viết 03:19 ngày 01/10/2018

với đặt tên đừng dùng sc, sv, ds… khó đọc lắm… Hãy gán tên sao mà khi đọc code mình hiểu nó nói gì

Scanner nhapDuLieu , Input , Output, etc
maSinhVien thay vì maSV
tenSinhVien
ArrayList sinhVienList / danhSach

kết thúc bạn sẽ có 1 vòng lập for (SinhVien sinhVien : danhSach)
cái danh sách có thể làm rõ bằng cách gán tên danh sách của ai (danhSachSinhVien)…
dễ hiểu hơn rất nhiều là đọc for (SinhVien sv:ds) - ý kiến cá nhân của mình về cách đặt tên

When I Wrote It, Only God and I Knew the Meaning; Now God Alone Knows

Bài liên quan
0