Hỏi về vấn đề kiểm tra trong ArrayList

Mình dang viết 1 ctql khi mình viết hàm add thi thì gặp vấn đề với hàm container(Object) . Đoạn code hàm add như thế này :slight_smile:

 public boolean add1(Student student) {
			if(!listStudents.contains(student)) {
				System.out.println("ko co " );
				return listStudents.add(student);
  
			}
			else 
				System.out.println("++co student++ "+student);
			inds();
			return false;
	 } 

Khi compile mình add thong tin lần đầu thì nó add bình thường nhưng tới lần thứ 2 mình thử nhập trùng id xem nó có kiểm tra trùng lặp khộng thì lần này nó cũng cho add luôn . Vậy cho hỏi hàm container(Object) kiểm tra theo cơ chế gi hoặc do mình viết hàm add bị sai. Bác nào có kn sửa dùm.
đây là kq sau khi nhâp

|33|asdfsd|22|asdfsd|3.0|
|id|-name-|-age--|---|---|
|33|sadas|33|asdas1|2.0|

Bạn phải override lại method equals trong class Student

4 Likes

Override như thế nào bạn mình show class Student như vầy bạn chỉ dùm :

public class Student implements Serializable{
	private static final long serialVersionUID = 1L;

	private String name,address;
	private int id;
	private byte age;
	private float gpa;//diem tb
	public Student() {
		}
	public Student (int id,String name ,byte age,String address,float gpa) {
		
		super();
		this.id = id;
		this.name= name;
		this.address=address;
		 this.age=age;
		 this.gpa=gpa;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public byte getAge() {
		return age;
	}

	public void setAge(byte age) {
		this.age = age;
	}

	public float getGpa() {
		return gpa;
	}

	public void setGpa(float gpa) {
		this.gpa = gpa;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", address=" + address + ", id=" + id + ", age=" + age + ", gpa=" + gpa + "]";
	}
	
}

contains(Object)

so sánh theo cơ chế giá trị và địa chỉ vùng nhớ của object nhé bạn.

2 Likes

Mình thấy mấy cái student của bạn khác nhau mà? Các object khác nhau, mặc dù có cùng id.

Mình hiểu bạn muốn check theo id.
Thay vì làm cách phức tạp và tiềm ẩn nhiều nguy cơ là kiểm tra bằng contains() (phải override equal()hashCode()), có cách đơn giản hơn:

//if(!listStudents.contains(student))
if(listStudents.stream().noneMatch(std -> std.getId() == student.getId()))
4 Likes

Mình sửa dc rồi .Mình chon ghi đè equals() do mình đọc khộng ra ý nghỉa đoạn code của bạn Trần Hoàn . Thì ra trong Student mình viết thêm hàm equals() so sánh id là dc vậy mà mình đọc nhiều lân mà không bik hàm này còn có tác dụng bổ sung cho container(Object ) .
Như vậy chỉ cần viết hàm equals chỉ so sanh id thôi mình viết thế này :

 public boolean equals(Object obj) {
	        if (obj instanceof Student) {
	            Student another = (Student) obj;
	            //Chu y vi id la int nen dung == neu la String thi dung equal
	            if (this.getId()==another.getId()) {
	                return true;
	            }
	        }
	        return false;
	    }

Như vây hàm add của mình :

 public boolean add1(Student student) {
	        int size = listStudents.size();
			if(!listStudents.contains(student)) {
      				System.out.println("ko co " );
			return listStudents.add(student);
  
			}
			else {
				System.out.println(" Co student nay : "+student);
				}
			System.out.println(" Size hien tai la : "+ size);
			System.out.println(" In lai danh sach ");
			inds();

			return false;
	 }
1 Like

Chắc bạn đang học trong trường nên thầy cô chỉ dạy bạn những thứ cơ bản. Nếu bạn làm việc với Java thường xuyên, bạn sẽ thấy stream rất hữu dụng, dùng dần sẽ quen. Nó trừu tượng hoá các vật thể “hữu hình” là List, Map, Set, Collection, Array… thành một tập hợp dữ liệu là Stream.

Stream giúp bạn kiểm tra và biến đổi giữa các dạng dữ liệu khác nhau, như đoạn code trên có ý nghĩa là

if (trong stream của listStudents không có đối tượng "std" nào mà std.getId() == student.getId())

Nói chung là làm cho code ngắn, tường minh (giống suy nghĩ của con người), dễ tái sử dụng, chứ hiệu năng thì cũng bình thường.

4 Likes

Không phải cơ bản hay nâng cao mà cái này có từ Java 8, thầy cô dạy Java 7 muốn dạy nâng cao cũng không có :v Stream

3 Likes

Thank bác ! Mình đã xem qua về Stream , đây quả thật là 1 giải pháp hay cho csdl lớn .Mặc dù chưa hiểu lắm về ý nghĩa của

std -> std.getId()  
// mình không bik là cái std->std mang ý nghĩa gi , nó là do mình tuy y tạo ra hay theo 1 tieu chuẩn nào và std là biến hay object 

trên web mình thấy họ khai báo chổ này rồi in luon. vd s->s trong doạn code này :

import java.util.Arrays;
import java.util.List;
 
public class Example {
 
	public static void main(String[] args) {
		List<String> names = Arrays.asList("Khanh", "Thanh", "Dung");
 		names.stream()
			.filter(s -> s.startsWith("K"))  
			.forEach(System.out::println);
	}     }

Toán tử mũi tên đó gọi là lambda expressions, còn dấu ::method references

public static void main(String[] args) {
	List<String> names = Arrays.asList("Khanh", "Thanh", "Dung");
	names.stream().filter(s -> s.startsWith("K"))
                  .forEach(s -> System.out.println(s));
}
4 Likes

mình không bik là cái std->std mang ý nghĩa gi , nó là do mình tuy y tạo ra hay theo 1 tieu chuẩn nào và std là biến hay object

Ừ thì, nó do mình tuỳ ý tạo ra, giống như ta thường nói “Tìm những số nguyên X nào đó trong tập hợp số nguyên này mà X vừa chẵn vừa dương”, thì câu lệnh sẽ là

List<Integer> original...//Tự khai báo
List<Integer> filtered = original.stream()
                                 .filter(X -> X % 2 == 0 && X > 0)
                                 .collect(Collectors.toList());

collect() là method để biến đổi một stream (cái trừu tượng) thành một vật thể cụ thể thông qua một Collectors, trong trường hợp này là List.
Generic (cái dấu < >) của Java đủ thông minh để hiểu được kiểu dữ liệu.
originalList<Integer> → stream là Stream<Integer> → X là Integer → Collectors.toList() là List<Integer>

Nói chung là stream là một cái khá hay, lambda expreession cũng là cái khá hay, method reference cũng hay nốt, toàn mấy cái dễ xài, mì ăn liền, công nghiệp hoá :))

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?