int và Integer khác nhau như nào?

intInteger.png

int là một loại primitive type (Kiểu dữ liệu nguyên thủy)

Integer khi chuyển đổi qua lại với int thì được gọi là một wrapper class. Bản chất là class kế thừa từ object Number.

Primitive type Wrapper class
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double

 

Khi đề cập sự khác biệt giữa 2 loại int và Integer, qua sự chuyển đổi của chúng thì chúng ta sẽ “đụng” tới 2 lý thuyết cơ bản:

+ Autoboxing
+ Unboxing

Xét ví dụ:

import java.util.ArrayList;
import java.util.List;

public class Unboxing {

    public static void main(String[] args) {
        Integer i = new Integer(-8);

        /*1. Unboxing là khi chuyển từ Wrapper class (Integer) sang
primitive type (int)
(Unbox là bóc thằng to thành thằng nhỏ :d. Hiểu vậy cho dễ nhớ :)) )
        Unboxing thông qua việc gọi hàm. */
        /*bản chất mà chúng ta không nhìn thấy chỗ này,
i lúc đầu là Integer là một class đối tượng sẽ có các hàm
override từ Number: i.intValue() => i lúc này chuyển thành int*/
int absVal = absoluteValue(i);
System.out.println("absolute value of " + i + " = " + absVal);

        List<Double> ld = new ArrayList<Double>();
/*Π được autoboxed thông qua việc gọi hàm.
Chuyển từ double sang Double: Double.valueOf(3.1416) */
        ld.add(3.1416);
        /* 2. Unboxing thông qua việc gán.
Chuyển wrapper class Double thành double primitive type*/
        double pi = ld.get(0);
        System.out.println("pi = " + pi);
    }

    public static int absoluteValue(int i) {
        return (i > 0) ? -i : i;
    }
}

 

Thêm nữa, Integer là một Wrapper class con của Number. Đã là một đối tượng thì nó mang đầy đủ tính chất của một đối tượng.  Có các hàm mà bản thân Object Number define (toString, valueOf, intValue, intLong, compare… ) mà primitive type không có.

Ref: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Sự khác biệt giữa String, String Builder và StringBuffer

Một câu hỏi rất phổ biến và cơ bản trong giới lập trình java.

1. String được gọi là immutable (Không thể thay đổi được).

Ví dụ: Mình có chuỗi String str = “Khiemnd xin chào các bạn “;

Mình muốn thêm chuỗi “Cảm ơn các bạn đã ghé thăm blog” vào sau chuỗi str kia.

Đại loại các bạn sẽ làm như sau:

package com.khiemnd5.controler;

public class Test {

    public static void main(String[] args) {
        String str = "Khiemnd xin chào các bạn. ";
        str.concat("Cảm ơn các bạn đã ghé thăm blog");// concat là hàm nối chuỗi. Các bạn có thể thử với các hàm khác như replace,...

        System.out.println(str);
    }
}

Output các bạn nghĩ sẽ là gì?

  1. Khiemnd xin chào các bạn.
  2. Khiemnd xin chào các bạn. Cảm ơn các bạn đã ghé thăm blog

 

Câu trả lời là 1 đó. “Khiemnd xin chào các bạn.” Tại sao ư? Không như những gì bạn nghĩ đúng không? Vì String là immutable. Khi khởi tạo str thì giá trị “Khiemnd xin chào các bạn. ” được lưu vào Constant String Pool. Không thể thay đổi => thread safe (An toàn trong xử lý luồng). Nên hàm “concat” trong String dùng ở đây không có ý nghĩa gì.

Đọc tới đây trong đầu bạn sẽ vân mông lung vì các bạn rất hay thao tác với String theo một kiểu nữa(Thực ra mình cũng vậy :d). Bình tĩnh, các bạn hãy xem đoạn code phía dưới.

Cùng ý đồ bên trên. Nối chuỗi.

package com.khiemnd5.controler;

public class Test {

    public static void main(String[] args) {
        String str = "Khiemnd xin chào các bạn. ";
        str += "Cảm ơn các bạn đã ghé thăm blog";

        System.out.println(str);
    }
}

Output:?

=> Khiemnd xin chào các bạn. Cảm ơn các bạn đã ghé thăm blog

😀 Tại sao ư? Để mình giải thích nhé!

Đầu tiên như đã nói str sẽ được lưu vào Constant String Pool. Để đó đã. Sau đó, str += “Cảm ơn các bạn đã ghé thăm blog”; thì java lại tạo ra vùng nhớ mới trong Pool. Giá trị vùng nhớ mới + giá trị vùng nhớ cũ thì nó tạo ra chuỗi đó thôi:d (Một vùng nhớ mới hoàn toàn chứa cả str cũ và str được nối vào). Bản chất giá trị vùng nhớ cũ vẫn là “Khiemnd xin chào các bạn.” chứ nó không hề bị override (ghi đè) nhé. 

2.  String Buffer hay StringBuilder sinh ra để giải quyết các vấn đề còn tồn tại của String. Khi khởi tạo thì giá trị sẽ được lưu vào heap.

String thì là immutable. Còn StringBuilder hay StringBuffer là mutable (Có thể thay đổi giá trị_ giá trị là giá trị khởi tạo ban đầu với một khoảng vùng nhớ đã được cấp)

Về cơ bản thì StringBuffer hay StringBuilder đểu có những phương thức giống nhau.

Chỉ có khác ở chỗ. StringBuffer an toàn cho xử lý đồng bộ => thread safe. Nhưng lại chậm về mặt hiệu năng. StringBuilder thì ngược lại. Không xử lý luồng an toàn nhưng tốc độ lại nhanh.

 

=> Tùy vào tình huống sử dụng thực tế để áp dụng loại String nào cho hợp lý. 😀

Khi nối một chuỗi ngắn, đơn giản thì ko nhất thiết chúng ta cứ phải dùng StringBuilder hay Buffer làm gì. String vẫn làm tốt 😀

 

————————————————————————————————————————-
                                       String                    StringBuffer         StringBuilder
————————————————————————————————————————–
Storage Area | Constant String Pool           Heap                       Heap
Modifiable     |  No (immutable)            Yes( mutable )          Yes( mutable )
Thread Safe   |           Yes                                  Yes                              No
 Performance |         Fast                                Very slow                    Fast
————————————————————————————————————————–

 

Ref: http://javahungry.blogspot.com/2013/06/difference-between-string-stringbuilder.html

Cắt chuỗi bằng ký tự xuống dòng new line

Có 3 loại ký tự xuống dòng:

1 . \n trong Unix, New Mac

2. \r old Mac

3. \r\n Windows và DOS

Trong ví dụ này, mình sẽ dùng regex \r?\n để tìm ra ký tự xuống dòng.

Code:

public class SplitByNewLineExample {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("");
        sb.append("      aaa \n");
        sb.append("     bbbbb      \n");
        sb.append("ccccc      \n");
        sb.append("\n");
        sb.append("ddd\r\n");
        sb.append("\r\n");
        sb.append("eee\r\n");

        String text = sb.toString();

        System.out.println("----Du lieu cu----");
        System.out.println(text);

        System.out.println("----- Sau khi split ----");
        int count = 1;
        String[] lines = text.split("\\r?\\n");
        for (String line : lines) {
            System.out.println("Line" + count++ + " : "+  line);
        }
    }
}

Output: (do trình hiển thị text của wordpress nên text output ko đc chính xác khoảng cách)


----Du lieu cu----
aaa
bbbbb
ccccc

ddd

eee

----- Sau khi split ----
Line1 :             aaa
Line2 :           bbbbb
Line3 : ccccc
Line4 :
Line5 : ddd
Line6 :
Line7 : eee

 

Sử dụng StringUtils kiểm tra null hoặc empty

Quá phổ biến rồi.

Thông thường chúng ta vẫn check :

if(str != null && !str.isEmpty()) { /* do your stuffs here */ }

 

StringUtils có chứa hàm isEmpty() hàm này có tác dụng check được null or empty.  Nhìn đơn giản hơn nhiều :d

System.out.println(StringUtils.isEmpty("")); // true
System.out.println(StringUtils.isEmpty(null)); // true

 

Check khoảng trắng:

 

StringUtils.isBlank(String str); // – Checks if a String is whitespace, empty (“”) or null.

 

Đọc từng dòng trong file java 8

Code java 8 rất ngắn và có sự thay đổi rõ rệt, rất đơn giản.


import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
* @author khiemnd5
*Email:khiemnd5@gmail.com
*
* Apr 17, 2016
*/

/*
Nội dung file text.txt:

Welcome my blog Khiem Nguyen Dang
Hello
Hava a nice day
Xin chào mình là Nguyễn Đăng Khiêm

=> Java 8 sẽ đọc từng dòng trong file và in ra nội dung từng file thông qua stream là một điểm mới trong java 8(Lambada).
*/
public class ReadFromFileJava8 {
public static void readFile(){
String fileName = "/users/khiemnd5/text.txt";//bạn hãy thay đổi đường dẫn tới file của bạn
// int []i ={0};//i là biến đếm xem chúng ta đã in tới dòng nào
try(Stream<String> stream = Files.lines(Paths.get(fileName))){
stream.forEach(line ->{
//line là từng dòng trong file, tại đây bạn có thể tương tác với nội dung của file. Ở đây, mình chỉ in ra nội dung của từng dòng

// System.out.println(line +" is number line "+ i[0]++);//in ra cả nội dung file và dòng thứ mấy ta vừa in, bắt đầu từ 0
System.out.println(line);
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
readFile();
}
}

Kết quả in ra:
Screen Shot 2016-04-17 at 1.15.16 PM

BigInteger trong java

***********************************************************************

                                                                    Các mã lệnh và thuật toán

1.Hàm sinh 1 số nguyên lớn ngẫu nhiên 

 SecureRandom r = new SecureRandom();

2. Các phép toán trong BigInteger

Phép cộng:

BigInteger a = new BigInteger();
BigInteger b = new BigInteger();
BigInteger add = new BigInteger();
add=a.add(b);

Phép trừ:

BigInteger a = new BigInteger();
BigInteger b = new BigInteger();
BigInteger sub = new BigInteger();
sub=a.subtract(b);

Phép nhân:

BigInteger a = new BigInteger();
 BigInteger b = new BigInteger();
BigInteger mul= new BigInteger();
mul=a.multiply(b);

Phép chia:


BigInteger a = new BigInteger();
BigInteger b = new BigInteger();
BigInteger div= new BigInteger(); div=a.division(b);

3. Hàm khởi tạo số nguyên lớn từ một chuỗi

BigInteger(string s, int radix);

Với s là chuỗi số nguyên lớn và radix là hệ cơ số (chẳng hạn 10 => hệ thập phân).

Ví dụ:

BigInteger k = new BigInteger(“123456”, 10); //k=123456

4. Hàm sinh ngẫu nhiên một số nguyên tố lớn

static BigInteger genPseudoPrime(int bits, int confidence, Random rand);

Sinh ngẫu nhiên một số nguyên tố lớn có số bit là bits, độ tin cậy của thuật toán xác suất kiểm tra số nguyên tố Rabin Miller là confidence và độ ngẫu nhiên là rand.
// Ví dụ: sinh ngẫu nhiên số nguyên tố dài 512 bit, độ tin cậy là 50.

BigInteger p = BigInteger.genPseudoPrime(512, 50, new Random());

5. Hàm tính ước số chung lớn nhất

public BigInteger GCD(BigInteger bi)
	// Tính ước số chung lớn nhất của hai số nguyên k và phi
	k.GCD(phi); 

6. Hàm tính phần tử ngược

public BigInteger modInverse(BigInteger modulus)
	// Tìm d là phần tử ngược của e trên vành số nguyên phi
	d = e.modInverse(phi); 

5. Hàm tính am mod n

public BigInteger modPow(BigInteger exp, BigInteger n)

// Tìm m = m^e mod n
Ví dụ: m = m.modPow(e, n);

Viết tiếp vào file nếu file đã có dữ liệu dùng DataOutputStream

public boolean writeToFile(String dataLine) {
  dataLine = &amp;quot;\n&amp;quot; + dataLine;
  try {
    File outFile = new File(filepath);
    dos = new DataOutputStream(new FileOutputStream(outFile,true));//true Writing to an already existing file
    dos.writeBytes(dataLine);
    dos.close();
  } catch (FileNotFoundException ex) {
    return (false);
  } catch (IOException ex) {
    return (false);
  }
  return (true);
}

UML Class Diagram Relationships, Aggregation, Composition

http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html

There are five key relationships between classes in a UML class diagram :

Dependency – Association

Aggregation

Composition

Inheritance

Realization

These five relationships are depicted in the following diagram:UML

UML Class Relationships

The above relationships are read as follows:

  • Dependency : class A uses class B
  • Aggregation : class A has a class B
  • Composition : class A owns a class B
  • Inheritance : class B is a Class A  (or class A is extended by class B)
  • Realization : class B realizes Class A (or class A is realized by class B)

What I hope to show here is how these relationships would manifest themselves in Java so we can better understand what these relationships mean and how/when to use each one.

Dependency/association is represented when a reference to one class is passed in as a method parameter to another class. For example, an instance of class B is passed in to a method of class A:

public class A {

public void doSomething(B b) {   }

}

 

Now, if class A stored the reference to class B for later use we would have a different relationship called Aggregation. A more common and more obvious example of Aggregation would be via setter injection:

 

public class A {

      private B bb;

      public void setB(B b) { bb = b; }

      }

Aggregation is the weaker form of object containment (one object contains other objects). The stronger form is called Composition. In Composition the containing object is responsible for the creation and life cycle of the contained object. Following are a few examples of Composition.

  • First, via member initialization:

public class A {

      private B b = new B();

}

  • Second, via constructor initialization:

public class A {

      private B bb;

      public A() {

        bb = new B();

    }

}// default constructor

  • Third, via lazy init:

public class A {

    private B _b;

    public B getB() {

        if (null == _b) {

            _b = new B();

        }

        return _b;

    } // getB()

 

 

 

Inheritance is a fairly straightforward relationship to depict in Java:

public class A {

      

  } // class A

  

public class B extends A {

      ….

  } // class B

Realization is also straighforward in Java and deals with implementing an interface:

public interface A {

      

  } // interface A

  

public class B implements A {

      

  } // class B