300x250 AD TOP

Thank you so much for taking the time for sharing your knowledge with me

Powered by Blogger.

Friday, July 6, 2018

Tagged under:

Java Set – Set trong Java

Java Set – Set trong Java

Java Set là một tập hợp các phần tử hoặc đối tượng(Objects), các phần tử này không trùng lặp. Java Set là một interface được thừa kế từ Collection interface. Không giống như List, Java Set KHÔNG phải là 1 tập thứ tự, các phần tử của nó KHÔNG có một thứ tự nhất định. Java Set KHÔNG cung cấp truy cập qua vị trí, và nơi bạn chèn phần từ vào Set. Bạn không thể truy cập phần tử bằng vị trí(index) và tìm kiếm kiếm phần tử trong danh sách.

Java Set

Trong phần này, tôi sẽ trình bày về những điểm quan trọng của Java Set:

  1. Java Set interface là một thành viên(member) của Java Collections Framework.
  2. Không giống như List, Set KHÔNG cho phép bạn thêm vào những phần tử trùng lặp.
  3. Set cho phép bạn thêm duy nhất 1 phần từ null.
  4. Set interface có 1 hàm mặc định(default method) trọng Java 8: spliterator.
  5. Không giống như List và mảng(Array), Set KHÔNG hỗ trợ chỉ mục(index, position) của phần tử.
  6. Set hỗ trợ kiểu Generics và chúng ta nên sử dụng nó khi có thể. Sử dụng kiểu Generic trong Set sẽ giúp bỏ qua vấn đề ClassCastException trong thời gian chạy(runtime).
  7. Chúng ta có thể sử dụng thực thi(implementations) Set interface để duy trì những phần tử duy nhất(unique)

Biểu đồ lớp(class) của Java Set

Java Set interface kế thừa(extend) từ Collection interface. Collection interface kế thừa từ Iterable interface. Những class thường thực thi(implementation) Set là: HashSet, LinkedHashSet, TreeSet, CopyOnWriteArraySet và ConcurrentSkipListSet. AbstractSet cung cấp 1 bộ khung thực thi(implementation) của Set interface vì thế các class kế thừa AbstractSet không cần thực thi(implementation) lại.



Các hàm trong Java Set

Trong phần này tôi sẽ trình bày các hàm thông dụng trong Java Set:
int size(): Trả về số lượng phần tử trong Set.
boolean isEmpty(): Kiểm tra Set có bị rỗng hay không.
boolean contains(Object o): Trả về tru nếu phần tử được tìm thấy.
Iterator iterator(): Trả về object Iterator dùng để duyệt các phần tử trong Set. Các phần tử trả về không có thứ tự nhất định.
Object[] toArray(): Trả về mảng các phần tử trong Set. Thứ tự của các phần tử trả về trong iterator sẽ giống với thứ tự mảng.
boolean add(E e): Thêm 1 phần tử vào trong Set nếu phần tử đó chưa tồn tại trong Set.
boolean remove(Object o): Xóa 1 phần tử trong Set nếu phần tử đó tồn tại.
boolean removeAll(Collection c): Xóa tất cả các phần tử trong Set mà tồn tại trong collection.
boolean retainAll(Collection c): Chỉ giữ lại các phần tử tồn tại trong collection, các phần tử khác sẽ bị xóa bỏ.
void clear(): Xóa tất cả các phần tử trong Set.

Chuyển đổi Mảng(Array) thành Set

Không giống như List, chúng ta KHÔNG thể chuyển đổi mảng(Array) thành Set một cách trực tiếp
Vì thế chúng ta KHÔNG thể sử dụng lớp mảng(Array class) để chuyển đổi. Chúng ta có thể tiếp cận bằng cách khác. Chúng ta có thể chuyển đổi mảng(array) thành List bằng cách sử dụng hàm Arrays.asList(), sau đó sử dụng nó để tạo ra một Set. Bằng cách này, chúng ta có thể chuyển đổi 1 Java Array theo 2 cách. Chúng ta sẽ tham khảo từng cách một theo hướng dẫn dưới đây.
Cách 1:
Trong cách này, đầu tiên chúng ta cần tạo ra 1 List từ mảng cho trước và dùng nó để tạo ra 1 Set:
import java.util.*;

public class ArrayToSet {
   public static void main(String[] args) {
  
 String[] vowels = {"a","e","i","o","u"};
  
 Set<String> vowelsSet = new HashSet<String>(Arrays.asList(vowels));
 System.out.println(vowelsSet);
 
 /**
  * Unlike List, Set is Not backed by array, 
  * so we can do structural modification without any issues.
  */
 vowelsSet.remove("e");
 System.out.println(vowelsSet);
 vowelsSet.clear();
 System.out.println(vowelsSet);
   }
}
Cách 2:
Với cách tiêp cận này, chúng ta KHÔNG cần sử dụng List làm trung gian để tạo ra Set từ Array. Đầu tiên tạo một HashSet rỗng, sau đó sử dụng Collection.addAll() để copy các phần tử trong mảng vào Set.
import java.util.*;

public class ArrayToSet2 {
   public static void main(String[] args) {
  
 String[] vowels = {"a","e","i","o","u"};
  
 Set<String> vowelsSet = new HashSet<>();
 Collections.addAll(vowelsSet, vowels); 
 System.out.println(vowelsSet);

 /** 
  * Unlike List, Set is NOt backed by array, 
  * so we can do structural modification without any issues.
  */
 vowelsSet.remove("e");
 System.out.println(vowelsSet);
 vowelsSet.clear();
 System.out.println(vowelsSet);
   }
}
Kết quả:
Khi chúng ta chạy 2 chương trình trên điều xuất ra kết quả giống nhau
[a, e, u, i, o]
[a, u, i, o]
[]

Chuyển Java Set thành mảng(Array)

Trong phần này, chúng ta sẽ viết 1 chương trình chuyển một tập Set String thành Mảng(Array) String bằng cách sử dụng hàm Set.toArray() như bên dưới:
import java.util.*;

public class SetToArray {
   public static void main(String[] args) {
 Set<String> vowelsSet = new HashSet<>();

 // add example
 vowelsSet.add("a");
 vowelsSet.add("e");
 vowelsSet.add("i");
 vowelsSet.add("o");
 vowelsSet.add("u");
  
 //convert Set to Array
 String strArray[] = vowelsSet.toArray(new String[vowelsSet.size()]);
 System.out.println(Arrays.toString(strArray)); 
   }
}
Kết quả:
Khi ta chạy chương trình trên, kết quả sẽ xuất ra như sau:
[a, e, u, i, o]

Sắp xếp trong Java Set

Như chúng ta được biết Set(HashSet) KHÔNG hỗ trợ sắp xếp các phần tử một cách trực tiếp. Nó sắp xếp và hiển thị các phần tử một cách ngẫu nhiên.
Tuy nhiên ta có cách sắp xếp các phần tử như sau:
Chuyển Java Set thành List sau đó sử dụng Collections.sort() để sắp xếp mảng
import java.util.*;

public class SetSortingExample {

 public static void main(String[] args) {
  Set<Integer> intsSet = new HashSet<>();
  Random random = new Random();
  for(int i = 0; i <= 10; i++) {
 intsSet.add(random.nextInt(1000)) ;
  }
  
  System.out.println("Before Sorting: " + intsSet);
  
  List listASC = new ArrayList<Integer>(intsSet);
  
  Collections.sort(listASC, new Comparator<Integer>() {
        public int compare(Integer a, Integer b) {
        return a - b;
        }
  });
  
  System.out.println("ASC Sorting: " + listASC);
  
  List listDES = new ArrayList<Integer>(intsSet);
  
  Collections.sort(listASC, new Comparator<Integer>() {
 public int compare(Integer a, Integer b) {
  return b - a;
        }
  });
  
  System.out.println("DES Sorting: " + listASC);
 }
}

Kết quả:
Khi chúng ta chạy chương trình trên sẽ xuất ra kết quả như sau:
Before Sorting: [976, 241, 868, 518, 599, 776, 954, 939, 92, 173, 207]
ASC Sorting: [92, 173, 207, 241, 518, 599, 776, 868, 939, 954, 976]
DES Sorting: [976, 954, 939, 868, 776, 599, 518, 241, 207, 173, 92]

Java Set những toán tử thông dụng

Hầu hết những toán tử thông dụng hay được thực thi trên Java Set là add, addAll, clear, size. Dưới đây là ví dụ về những hàm hay được sử dụng trong Java Set
import java.util.*;

public class SetCommonOperations 
{
   public static void main(String args[]) 
   {
 Set<String> vowels= new HashSet<>();
  
 //add example
 vowels.add("A");
 vowels.add("E");
 vowels.add("I");

 //We cannot insert elements based on index to a Set
 System.out.println(vowels);
  
 Set<String> set = new HashSet<>();
 set.add("O");
 set.add("U");
 
 //appending set elements to letters
 vowels.addAll(set);
 System.out.println(vowels);
 
 //clear example to empty the set
 set.clear();
  
 //size example
 System.out.println("letters set size = " + vowels.size());
  
 vowels.clear();
 vowels.add("E"); vowels.add("E");vowels.add("I"); vowels.add("O");
 System.out.println("Given set contains E element or not? = " + vowels.contains("E"));
  
   }
}

Kết quả:
[A, E, I]
[A, E, U, I, O]
letters set size = 5
Given set contains E element or not? = true

Java Set duyệt các phần tử

Dưới đây là ví dụ đơn giản để duyệt các phần tử trong Java Set
import java.util.*;

public class SetIteratorExample
{
   public static void main(String[] args) 
   {

 Set<Integer> set = new HashSet<>();
 for(int i=0; i<5; i++) 
  set.add(i);
  
 Iterator iterator = set.iterator();
 
 //simple iteration
 while(iterator.hasNext()){
  int i = (int) iterator.next();
  System.out.print(i + ", ");
 }
 System.out.println("\n" + set);
 
 //modification of set using iterator
 iterator = set.iterator();
 while(iterator.hasNext()){
  int x = (int) iterator.next();
  if(x%2 ==0) iterator.remove();
 }
 System.out.println(set);
  
 //changing set structure while iterating
 iterator = set.iterator();
 while(iterator.hasNext()){
                //ConcurrentModificationException here
  int x = (int) iterator.next(); 
  if(x==1) set.add(10);
 }
   }
}

Kết quả
0, 1, 2, 3, 4, 
[0, 1, 2, 3, 4]
[1, 3]
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextNode(Unknown Source)
 at java.util.HashMap$KeyIterator.next(Unknown Source)
 at com.vn.programming.MultipleThread.main(MultipleThread.java:33)
Đoạn dưới đây quăng lỗi ConcurrentModificationException bởi vì chứ ta không thể thay đổi cấu trúc của set khi duyệt interator
while(iterator.hasNext()){
                //ConcurrentModificationException here
  int x = (int) iterator.next(); 
  if(x==1) set.add(10);
 }

Java Set sang Stream

Ví dụ dưới đây hướng dẫn chuyển Java Set thành Stream
import java.util.*;

public class SetToStream {

   public static void main(String[] args) {
 Set<String> vowelsSet = new HashSet<>();
 // add example
 vowelsSet.add("a");
 vowelsSet.add("e");
 vowelsSet.add("i");
 vowelsSet.add("o");
 vowelsSet.add("u");
  
 //convert set to stream
 vowelsSet.stream().forEach(System.out::println);
   }
}
Kết quả
a
e
u
i
o

Monday, July 2, 2018

Tagged under:

Thread.sleep() trong Java – Java Thread sleep


Thread.sleep trong Java

  • Phương thức Thread.sleep() được sử dụng để tạm dừng thực thi của thread theo thời gian 1/1000 giây(milliseconds). Đối số milliseconds bắt buộc là số dương, nếu bạn nhập số âm sẽ xuất lỗi IllegalArgumentException.
  • Có một phương thức khác là sleep(long millis, int nanos) có thể sử dụng để tạm dừng thực thi của thread với giá trị truyền vào là 1/0000 (miniseconds) và 1 phần tỉ (nanoseconds). Giá trị của nano second là từ 0 đến 999999.

Ví dụ về Java Thread Sleep

Mình sẽ viết 1 chương trình đơn giản để tạm dừng thực thi của thread trong 2 giây.
ThreadSleep.java file.
package com.journaldev.threads;

public class ThreadSleep {

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(2000);
        System.out.println("Sleep time in ms = "+(System.currentTimeMillis()-start));
        
    }

}

Nếu bạn chạy chương trình trên thì sẽ xuất ra thời gian lớn hơn 2000. Bởi vì đó là cách hoạt động thread sleep và hệ điều hành thực thi thread scheduler.

Những điểm quan trọng của Thread Sleep

  1. Thread Sleep luôn luôn tạm dừng Thread đang thực thi.
  2. Thời gian chính xác của thread sleep trước khi gọi và bắt đầu thực thi được dựa vào thời gian và lịch trình của hệ thống (system timers và schedulers). Khi hế thống nhàn rỗi, thời gian thực của sleep gần bằng với thời gian chỉ định nhưng khi hệ thống bận thì thời gian sẽ tăng lên.
  3. Thread sleep không mất bất kỳ sự giám sát hay khóa (monitors or locks) của thread hiên tại.
  4. Bất kỳ thread nào ngắt ngang, phá vỡ (interrupt) thread trong lúc sleep, thì chương trình sẽ xuất lỗi InterruptedException.

Cách hoạt động của Thread Sleep

Thread.sleep tương tác với lịch trình thread(thread scheduler) để truyền thời gian chờ. Khi thời gian chờ kết thúc, thread chuyển sang chạy thái runnable và đợi CPU thực thi. Vì thể thời gian chính xác của thread sleep phụ thuộc và thread scheduler. Thread scheduler là 1 phần của hệ điều hành.

Nguồn: Thread sleep in java