JAVA筆記整理-包的結構與功能介紹
一、包的結構與功能介紹
Java是一門面向物件的語言,sun公司提供基於面向物件的幫助文件(API Application Program Interface) ,並針對不同的版本生成的API ,API中根據不同的功能分如下包 (package)
- java.applet.* : java的小應用程式
- java.awt.* 和 java.swing.* : java的圖形使用者介面(開發單機版的小遊戲)
- java.lang.* : java的語言包
- java.util.* : java的工具類包、集合框架包
- java.io.* : java檔案讀寫包(Input 、Output)
- java.net.* : java的網路程式設計包(Socket機制相關,URL)
- java.sql./ javax.sql. : java的資料庫操作
- java.lang.reflect.* 反射相關包
二、java的lang包
一、包裝類
定義: Java的8個基本資料型別對應的 物件型別,稱為它們的包裝類
為什麼需要包裝類:
基本資料型別中不能提供方法, 不能與其他引用資料型別轉換,此時包裝類作為該基本資料型別的物件型別,不僅提供常用的方法,還可以與其他資料型別互相轉換 和 “裝箱”、“拆箱”
基本資料型別 | 包裝型別 | 包裝類的預設值 |
---|---|---|
byte | Byte | null |
short | Short | null |
int | Integer | null |
long | Long | null |
float | Float | null |
double | Double | null |
char | Character | |
boolean | Boolean |
問題1: 基本資料型別、包裝類以及字串的相互轉換
public static void main(String[] args) { // 1、byte 的包裝類 Byte // 建立包裝類的物件 byte b=123; Byte obj1 = new Byte(b); //1、 包裝類 轉字串 包裝類物件.toString() String s1 = obj1.toString(); //2、字串轉包裝類 new 包裝類(s) 或者 包裝類.valueOf(s) String s2="100"; Byte obj2 = new Byte(s2); // 或者 Byte obj3 = Byte.valueOf(s2); //3 獲取包裝類的數值,包裝類轉基本資料型別 Byte - > byte // 包裝類.valueOf(基本資料型別) 或者 byteValue() byte b2 = obj2; // 包裝類可以直接複製給基本資料型別 ,這個過程 “拆箱”過程 byte b3 = Byte.valueOf(obj2); // 4、字串轉 基本型別 包裝類.paseByte(s) byte b4 = Byte.parseByte(s2); byte b5=122; String s5 = new Byte(b5).toString(); }
再以 Integer 舉例
public static void main(String[] args) {
int n=250;
// 轉包裝類
Integer obj1 = new Integer(n);
//包裝類轉基本資料型別
int n3 = Integer.valueOf(obj1);
// 轉字串
String s1 = obj1.toString();
// 字串再轉成 Integer
Integer obj2 = Integer.parseInt(s1);
Integer obj3 = new Integer(s1);
// 字串轉int
int n2 = Integer.valueOf(s1);
// int 轉 轉字串
String s3 = new Integer(n2).toString();
System.out.println("-------------Intger的常用方法------");
int num = Integer.bitCount(2); // 個位數 + 高位數的和
System.out.println(num);
// n1>n2 返回1 n1==n2 返回0 n1<n2 -1
//比較兩個數是否相等
System.out.println(Integer.compare(100,200));
System.out.println(Integer.decode("123"));
//equals 比較兩個數是否相等 對於基本資料型別的包裝類比較他們的數值
Integer n1 = new Integer(90);
Integer n4 = new Integer(90);
System.out.println(n1.equals(n4));// 比較兩個物件的 值
System.out.println(n1 == n4);// 比較 兩個物件的地址
int n5 =100;
int n6 =100;
System.out.println(n5==n6);// 對於基本資料型別 == 比較的值
// 進位制轉換
System.out.println(Integer.toBinaryString(18));//轉成二進位制表示形式
System.out.println(Integer.toHexString(15));//轉成16進製表示形式
System.out.println(Integer.toOctalString(10));//轉成8進製表示
}
問題2: 資料型別的裝箱和拆箱
裝箱: 將基本資料型別自動轉換成 它的包裝類,可以使用包裝類的方法和屬性
// 自動裝箱: 100自動轉成 Integer
Integer num1 = 100;
拆箱: 將包裝型別 自動轉成 對應的基本資料型別。
// 自動拆箱: Integer 自動轉成 int
int num2 = num1;
面試題:
public static void main(String[] args) {
// 包裝類
// 自動裝箱: 100自動轉成 Integer
Integer num1 = 100;
// 自動拆箱: Integer 自動轉成 int
int num2 = num1;
Integer n1 =100;
Integer n2 =100;
System.out.println(n1.equals(n2)); //true
System.out.println(n1 == n2);// 應該true 他們同時指向常量池100
Integer n3 = 150; // 等價於 Integer n3 = new Integer(150);
Integer n4 = 150; // 等價於 Integer n4 = new Integer(150);
System.out.println(n3.equals(n4));//true
System.out.println(n3 == n4);//false
Integer n6 = new Integer(100);// 一定會建立新物件
System.out.println(n6 == n1); // false
}
//結論
//對於 -128 <=Integer的值 <=127 之間(byte範圍),
// 裝箱時不會建立新物件 而是直接引用 常量池中的值
// 如果超出byte 的返回,則自動建立新物件,各自指向新物件的記憶體
二、Object類
Object類是lang包提供的 ,對於lang包的類不需要import,所以 Object類無處不在,你不需要自己建立
常用方法
a、getClass: 返回該物件的型別 任何類都有它的型別
b、equals : Java中所有的equals 方式都是重寫Object的方法
原生的equals 比較的是 物件的地址 ,我們通常說的 equals比較兩個物件的值是因為幾乎所有的資料型別(包裝類,String)都重寫了equals 方法的
public boolean equals(Object obj) {
return (this == obj);
}
c、 hashCode() : 返回該都物件的hash值
// Object中的hashCode 本身沒有實現 ,
/**
* 1、對於基本資料型別的包裝類 其值就是其本身
* 2、對於String型別的HashCode ,也是String自己實現的,其演算法目的儘可能減少hash衝突
* 3、對於自定義類,需要你自己重寫HashCode ,如果不重寫 就在程式執行期間 JVM根據記憶體地址
* 類自動分配。(原則: 根據每個有意義的屬性值,計算各自的hashCode 相加等一系列操作得到)
*/
d:finalize() 資源回收呼叫該方法, 當物件地址不在被引用時,會被GC回收 並呼叫該方法
Object obj = null ;
5: toString() : 返回該物件的字串表現形式 (通常會被子類重寫)
wait():執行緒等待
notify():喚醒其中一個等待的執行緒
notifyAll:喚醒所有等待中的執行緒
物件的比較
public class Student {
private int id; //學生編號
private String sname;
private Integer age;
public void showInfo(){
System.out.println( sname +"---"+ age);
}
public Student(){
}
public Student(int id ,String sname ,int age){
this.id = id;
this.sname = sname;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
// 判斷型別 是否一致
if(obj instanceof Student){
// 強轉
Student stu = (Student)obj;
// 開始比較 id 和 sname
if(this.id == stu.id && this.sname.equals(stu.sname)){
return true;
}
}
return false;
}
@Override
public int hashCode() {
return id;
}
}
public static void main(String[] args) {
// 建立物件 比較物件是否相等
// 比較記憶體相等 或 比較值(物件的屬性)相等
Student stu1 = new Student(1001,"敖園",22);
Student stu2 = new Student(1001,"敖園",22);
System.out.println(stu1==stu2); // 比較兩個物件的地址 (不相等) false
System.out.println(stu1.equals(stu2)); // true
// 由於equals本身沒辦法解決
// 兩個物件因id 和name相等業務上是同一個物件的問題
// 所以需要重寫 equals 和 hashcode 。
// 為什麼要重寫HashCode呢?
// 回答: 在JMV中如果HashCode不相等,一定不能認為是同一個物件
Student stu3 = stu1; // stu3 的地址於stu1的地址是同一個
}
總結: 物件之間的比較 ,通常是比較屬性值,如果屬性值相等,我們可以認為是同一個物件,
此時需要重寫 equals 和hashcode方法。
為什麼要重寫HashCode呢?
回答: 在JMV中如果HashCode不相等,一定不能認為是同一個物件
三、System類
public static void main(String[] args) {
// System 屬於系統類
// System.out; // 獲取控制檯的列印流
// 設定JVM執行時 系統引數
System.setProperty("encoding","UTF-8");
System.out.println("獲取:"+System.getProperty("encoding"));
// 時間從 1970-01-01
System.out.println("獲取當前系統的時間毫秒數:"+ System.currentTimeMillis());
System.exit(0); // 0 : 表示JVM正常退出 -1 表示非正常退出
}
四、字串類
java.lang.String類,Java中所有的字串都會建立該類的例項 , 它可以對字串查詢,檢索,轉變大小寫,擷取等一系列操作,並提供了大量的字串操作方法。
String類的特點:
它是一個不可變字串 ,它的值建立後不能被改變。
String的構造器
// 建立字串物件
String s1="abc";
String s2 = new String("abc");
//通過字元陣列構建
char [] chars = {'a','b','c'};
String s3 = new String(chars); // 或指定長度構建字串
String s4 = new String(chars,0,2);
//或根據位元組陣列構建
byte [] byts = {97,98,99};
String s5 = new String(byts);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
System.out.println(s5);
// 字串是一個不可變的物件
// class類被JVM裝載時,會分配一個存放字串的常量池(String Pool)
// 在類載入時 先檢查常量池中是否有“abc”常量,如果有,直接將ss1指向該常量
// 如果沒有,則建立常量abc
// 建立2個物件
String ss1 = "abc";
// abc常量不能改變, 則再建立 abcd的常量,由ss1重新指向
ss1+="d";
// 建立3個物件
String ss2 ="abcd"; // abcd
String ss3 = "aaa"; // aaa
ss2 += ss3; // abcdaaa 重新建立abcdaaa並由ss2重新指向
String a1="abc";
String b1="abc"; // 兩個地址同時指向一個常量 “abc”
System.out.println(a1==b1); // true
System.out.println(a1.equals(b1));
String c1=new String("abc");// 堆記憶體中 對abc包裝後的地址
System.out.println(a1==c1); // false
System.out.println(a1.equals(c1));//true
字串類常用方法
- 將此字串與指定物件進行比較:
public boolean equals (Object anObject)
- 將此字串與指定物件進行比較,忽略大小寫:
public boolean equalsIgnoreCase (String anotherString)
舉例:
public static void main(String[] args) {
String s1 = "hello";
String s2 = "hello";
String s3 = "HELLO";
//boolean equese(Object obj):比較字串的內容是否相同
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println("-------------");
//boolean equalsIgnoreCose(String str):比較字串的內容是否相同,忽略大小寫
System.out.println(s1.equalsIgnoreCase(s2));
System.out.println(s1.equalsIgnoreCase(s3));
System.out.println("--------------");
}
4.1、獲取功能的方法
- 返回字串的長度:
public int length()
- 將指定的字串連線到該字串的末尾:
public String concat (String str)
- 返回指定索引處的char值:
public char charAt (int index)
- 返回指定字串第一次出現在該字串內的索引:
public int indexOf(String str)
- 返回一個子字串,從beginIndex開始擷取字串到字串結尾:
public String substring (int beginIndex)
- 返回一個子字串,從beginIndex到endIndex擷取字串。含beginIndex,不含endIndex
public String substring (int beginIndex,int endIndex)
舉例:
public static void main(String[] args) {
String s = "helloworld";
//length() :獲取字串的長度,其實也就是字元的個數
System.out.println(s.length());
System.out.println("---------");
//String concat (String str):將指定的字串連線到該字串的末尾
String s2 = s.concat("**hellow itheima");
System.out.println(s2);
//charAt(int index):獲取指定索引處的字串
System.out.println(s.charAt(0));
System.out.println(s.charAt(1));
System.out.println("-------");
//int indexOf(String str):獲取str在字串物件中第一次出現的索引,沒有返回-1
System.out.println(s.indexOf("l"));
System.out.println(s.indexOf("owo"));
System.out.println(s.indexOf("ak"));
System.out.println("---------");
//String sbustring(int start):擷取從start開始,到字串結尾的字串
System.out.println(s.substring(0));
System.out.println(s.substring(5));
System.out.println("----------");
//String substring(int start,int end):從start到end擷取字串,含start,不含end
System.out.println(s.substring(0,s.length()));
System.out.println(s.substring(3,8));
}
4.2、轉換功能的方法
- 將字串轉換為新的字元陣列:
public char[] toCharArray()
- 使用平臺的預設字符集將該String編碼轉換為新的位元組陣列:
public byte[] getBytes()
- 將與targer匹配的字串使用replacement字串替換
public String replace (CharSequence targer,CharSequence replacement)
舉例:
public static void main(String[] args) {
String s = "helloworld";
//char[] toCharArray():把字串轉換為字元陣列
char[] chs = s.toCharArray();
for(int x = 0 ; x < chs.length;x++){
System.out.println(chs[x]);
}
System.out.println("---------");
//byte[] getBytes():把字串轉換為位元組陣列
byte[] bytes = s.getBytes();
for(int x = 0;x < bytes.length; x++){
System.out.println(bytes[x]);
}
System.out.println("--------");
String str = "softeem";
String replace = str.replace("s","S");
System.out.println(replace);
}
4.3、分割功能的方法
將字串按照給定的regex(規則)拆分為字串陣列:public String[] split(String regex)
舉例:
public static void main(String[] args) {
String s = "aa|bb|cc";
String[] strArray = s.split("|");
for(int x = 0;x < strArray.length; x++){
System.out.println(strArray[x]);
}
}
五、StringBuffer和StringBuilder類
1、StringBuffer 類
是一個字串緩衝區的類,執行緒安全執行效率低,使用者儲存可變字串
構造器:
StringBuffer sb = new StringBuffer(); // 建立空字串的容器
StringBuffer sb = new StringBuffer(String);// 將字串使用容器儲存
StringBuffer sb = new StringBuufer(int);//宣告指定容量的容器
常用方法:
1.1、append():追加字串
1.2、delete(int start,int end):刪除指定位置的字元
1.3、insert(int start ,String):插入到指定位置
1.4、reverse():反轉字元
1.5、capacity():獲取初始容量
1.6、ensureCapacity(int):設定最低所需容量
2、StringBuilder類
也是字串緩衝區的類,它是執行緒不安全,且執行效率高的可變字串緩衝類
其StringBuilder的方法與StringBuffer幾乎一樣
3、面試題
1、StringBuffer、StringBuilder和String的區別
1、在執行速度上 : StringBuilder > StringBuffer > String
原因: String是字串常量,而StringBuilder和StringBuffer是字串變數,當需要改變字串內容時,Stirng重新建立變數並賦值, 而StringBuilder和StringBuffer可直接改原有的值,所有效率高,
2、線上程安全上: StringBuffer > StringBuilder > String
原因: StringBuffer是執行緒安全的,而StringBuilder執行緒不安全,在StringBuffer上的很多方法增加同步關鍵字(synchronized),導致在多個執行緒執行時,保持資料的完整性和一致性,而StringBuilder的方法並沒有同步 ,如果在多執行緒環境下為了確保資料安全,建議使用StringBuffer ,如果在單執行緒環境下,提高效率使用StringBuilder。