Java SE 重点知识笔记
文章目錄
- 前言:
- 1、Java概述
- 1.1、Java語言跨平臺原理:
- 1.2、JRE和JDK:
- 1.3、HelloWorld案例:
- 2、java基礎語法
- 2.1、注釋 :
- 2.2、類型轉換:
- 3、數(shù)據(jù)輸入
- 4、switch語句
- 4.1、switch語句練習-春夏秋冬:
- 3、String對象的特點
- 4、StringBuilder對象
- 3、ArrayList
- 4、繼承
- 5、修飾符
- 6、多態(tài)
- 7、抽象類
- 8、接口
- 9、內(nèi)部類
- 9、包裝類
- 10、時間日期類
- 11、異常
- 12、Collection集合
- 13、List集合
- 14、List集合的實現(xiàn)類
- 15、Set集合
- 16、Set集合排序
- 17、泛型
- 18、可變參數(shù)
- 19、Map集合
- 20、Collections集合工具類
- 21、File類
- 22、IO流
- 23、字節(jié)緩沖流
- 24、字符流
- 25、IO特殊操作流
- 26、多線程
前言:
學了半年的 Java web 發(fā)現(xiàn)還有一些 JavaSE 的知識沒有掌握,趁著這個暑假把 Java 的基礎知識補一下
1、Java概述
1.1、Java語言跨平臺原理:
Java程序并非是直接運行的,Java編譯器將Java源程序編譯成與平臺無關的字節(jié)碼文件(class文件),然后由Java虛擬機(JVM)對字節(jié)碼文件解釋執(zhí)行。所以在不同的操作系統(tǒng)下,只需安裝不同的Java虛擬機即可實現(xiàn)java程序的跨平臺。
1.2、JRE和JDK:
JVM(Java Virtual Machine),Java虛擬機
JRE(Java Runtime Environment),Java運行環(huán)境,包含了JVM和Java的核心類庫(Java API)
JDK(Java Development Kit)稱為Java開發(fā)工具,包含了JRE和開發(fā)工具
總結:我們只需安裝JDK即可,它包含了java的運行環(huán)境和虛擬機。
1.3、HelloWorld案例:
開發(fā)Java程序,需要三個步驟:編寫程序,編譯程序,運行程序。
1、HelloWorld案例的編寫:
2、HelloWorld案例的編譯和運行:
打開命令行窗口,將目錄切換至java文件所在目錄,編譯java文件生成class文件,運行class文件。
編譯:javac HelloWorld.java 執(zhí)行:java HelloWorld2、java基礎語法
2.1、注釋 :
單行注釋。單行注釋的格式是使用//,從//開始至本行結尾的文字將作為注釋文字。
// 這是單行注釋文字多行注釋。多行注釋的格式是使用/* 和 */將一段較長的注釋括起來。
/* 這是多行注釋文字 這是多行注釋文字 這是多行注釋文字 */2.2、類型轉換:
在Java中,一些數(shù)據(jù)類型之間是可以相互轉換的。分為兩種情況:自動類型轉換和強制類型轉換。
自動類型轉換:
- 把一個表示數(shù)據(jù)范圍小的數(shù)值或者變量賦值給另一個表示數(shù)據(jù)范圍大的變量。這種轉換方式是自動的。
例:
double num = 10; // 將int類型的10直接賦值給double類型 System.out.println(num); // 輸出10.0強制類型轉換:
- 把一個表示數(shù)據(jù)范圍大的數(shù)值或者變量賦值給另一個表示數(shù)據(jù)范圍小的變量。
例:
double num1 = 5.5; int num2 = (int) num1; // 將double類型的num1強制轉換為int類型 System.out.println(num2); // 輸出5(小數(shù)位直接舍棄)3、數(shù)據(jù)輸入
我們可以通過 Scanner 類來獲取用戶的輸入。使用步驟如下:
1、導包。Scanner 類在java.util包下,所以需要將該類導入。導包的語句需要定義在類的上面。
import java.util.Scanner;2、創(chuàng)建Scanner對象。
Scanner sc = new Scanner(System.in);// 創(chuàng)建Scanner對象,sc表示變量名,其他均不可變3、接收數(shù)據(jù)
int i = sc.nextInt(); // 表示將鍵盤錄入的值作為int數(shù)返回。例:
import java.util.Scanner; public class ScannerDemo {public static void main(String[] args) {//創(chuàng)建對象Scanner sc = new Scanner(System.in);//接收數(shù)據(jù)int x = sc.nextInt();//輸出數(shù)據(jù)System.out.println("x:" + x);} }4、switch語句
格式:
switch (表達式) {case 1:語句體1;break;case 2:語句體2;break;...default:語句體n+1;break; }執(zhí)行流程:
- 首先計算出表達式的值
- 其次,和case依次比較,一旦有對應的值,就會執(zhí)行相應的語句,在執(zhí)行的過程中,遇到break就會結束。
- 最后,如果所有的case都和表達式的值不匹配,就會執(zhí)行default語句體部分,然后程序結束。
4.1、switch語句練習-春夏秋冬:
功能:鍵盤錄入一個月份,請用程序實現(xiàn)判斷該月份屬于哪個季節(jié),并輸出。
示例代碼:
public class Demo1 { public static void main(String[] args) {// 鍵盤錄入月份數(shù)據(jù),使用變量接收Scanner sc = new Scanner(System.in);System.out.println("請輸入一個月份:");int month = sc.nextInt();switch (month) {case 12:case 1:case 2:System.out.println("冬季");break;case 3:case 4:case 5:System.out.println("春季");break;case 6:case 7:case 8:System.out.println("夏季");break;case 9:case 10:case 11:System.out.println("秋季");break;default:System.out.println("你輸入的月份有誤");}} }如果switch中得case,沒有對應break的話,則會出現(xiàn)case穿透的現(xiàn)象。
3、String對象的特點
1 創(chuàng)建字符串對象兩種方式的區(qū)別:
- 通過構造方法創(chuàng)建
通過 new 創(chuàng)建的字符串對象,每一次 new 都會申請一個內(nèi)存空間,雖然內(nèi)容相同,但是地址值不同。
上面的代碼中,JVM會首先創(chuàng)建一個字符數(shù)組, 然后每一次new的時候都會有一 個新的地址, 只不過s1和s2參考的字符串內(nèi)容是相同的。
- 直接賦值方式創(chuàng)建
以""方式給出的字符串,只要字符序列相同(順序和大小寫),無論在程序代碼中出現(xiàn)幾次,JVM 都只會建立一個 String 對象,并在字符串池中維護。
在上面的代碼中,針對第一行代碼, JVM會建立一個 String 對象放在字符串池中,并給s3參考,第二行則讓s4直接參考字符串池中的 String 對象,也就是說它們本質(zhì)上是同一個對象。
2、字符串的比較:
1、==號的作用 :
- 比較基本數(shù)據(jù)類型:比較的是具體的值
- 比較引用數(shù)據(jù)類型:比較的是對象地址值
2、equals方法的作用:
因為String是類,屬于引用類型,所以用equals來進行比較。
public boolean equals(String s) 比較兩個字符串內(nèi)容是否相同、區(qū)分大小寫4、StringBuilder對象
1、StringBuilder概述:
- StringBuilder是一個可變的字符串類,我們可以把它看成是一個容器,這里的可變指的是StringBuilder對象中的內(nèi)容是可變的。
String和StringBuilder的區(qū)別:
- String: 內(nèi)容是不可變的
- StringBuilder: 內(nèi)容是可變的
2、StringBuilder類的構造方法:
常用的構造方法:
示例代碼:
public class StringTest2 {public static void main(String[] args) {// public StringBuilder() :創(chuàng)建一個空白可變字符串對象,不含有任何內(nèi)容StringBuilder sb = new StringBuilder();System.out.println("sb:" + sb);System.out.println("sb. length():" + sb.length());// public Stri ngBuilder(String str) :根據(jù)字符串的內(nèi)容,來創(chuàng)建可變字符串對象StringBuilder sb2 = new StringBuilder("he11o");System.out.println("sb2:" + sb2);System.out.println("sb2. length():" + sb2.length());} }3、StringBuilder類添加和反轉方法:
添加和反轉方法:
示例代碼:
4、StringBuilder和String相互轉換:
StringBuilder轉換為String:
- public String toString():通過toString()就可以實現(xiàn)把StringBuilder轉換為String
String轉換為StringBuilder:
- public StringBuilder(String s) :通過構造方法就可以實現(xiàn)把String轉換為StringBuilder
3、ArrayList
1、ArrayList類概述:
什么是集合:
- 提供一種存儲空間可變的存儲模型,存儲的數(shù)據(jù)容量可以發(fā)生改變。
ArrayList集合的特點:
- 底層是數(shù)組實現(xiàn)的,長度可以變化。
泛型的使用:
- 用于約束集合中存儲元素的數(shù)據(jù)類型。
2、ArrayList類常用方法:
構造方法:
| public ArrayList() | 創(chuàng)建一個空的集合對象 |
成員方法:
4、繼承
1、 繼承的好處和弊端:
繼承好處:
- 提高了代碼的復用性(多個類相同的成員可以放到同一個類中)
- 提高了代碼的維護性(如果方法的代碼需要修改,修改一處即可)
繼承弊端:
- 繼承讓類與類之間產(chǎn)生了關系,類的耦合性增強了,當父類發(fā)生變化時子類實現(xiàn)也不得不跟著變化,削弱了子類的獨立性。
繼承的應用場景:
- 使用繼承,需要考慮類與類之間是否存在is…a的關系,不能盲目使用繼承。
- is…a的關系:誰是誰的一種,例如:老師和學生是人的一種,那人就是父類,學生和老師就是子類。
2. 繼承中的成員訪問特點:
2.1 繼承中變量的訪問特點:
在子類方法中訪問一個變量,采用的是就近原則。
示例代碼:
class Fu {int num = 10? }class Zi {int num = 20?public void show(){int num = 30?System.out.println(num)?} }public class Demo1 {public static void main(String[] args) {Zi z = new Zi()?z.show()? // 輸出show方法中的局部變量30} }2.2、super:
this&super關鍵字:
- this:代表本類對象的引用
- super:代表父類存儲空間的標識(可以理解為父類對象引用)
this和super的使用分別:
2.3 繼承中構造方法的訪問特點:
注意:子類中所有的構造方法默認都會訪問父類中無參的構造方法。
子類會繼承父類中的數(shù)據(jù),可能還會使用父類的數(shù)據(jù)。所以,子類初始化之前,一定要先完成父類數(shù)據(jù)的初始化,原因在于,每一個子類構造方法的第一條語句默認都是:super();
如果父類中沒有無參構造方法,只有帶參構造方法,該怎么辦呢?
2.4、繼承中成員方法的訪問特點:
通過子類對象訪問一個方法
2.5、 Java中繼承的注意事項:
- Java中類只支持單繼承,不支持多繼承。
錯誤范例:class A extends B, C { }
- Java中類支持多層繼承。
多層繼承示例代碼:
public class Granddad {public void drink() {System.out.println("爺爺愛喝酒")?} } public class Father extends Granddad {public void smoke() {System.out.println("爸爸愛抽煙")?} } public class Son extends Father {// 此時,Son類中就同時擁有drink方法以及smoke方法 }繼承練習:
例: 老師和學生
需求:定義老師類和學生類,然后寫代碼測試;最后找到老師類和學生類當中的共性內(nèi)容,抽取出一個父類,用繼承的方式改寫代碼,并進行測試。
class Person {private String name?private int age?public Person() {}public Person(String name, int age) {this.name = name?this.age = age?}public String getName() {return name?}public void setName(String name) {this.name = name?}public int getAge() {return age?}public void setAge(int age) {this.age = age?} } class Teacher extends Person {public Teacher() {}public Teacher(String name,int age) {super(name,age)?//調(diào)用父類的有參構造}public void teach() {System.out.println("用愛成就每一位學員")?} } class Student extends Person{public Student() {}public Student(String name, int age) {super(name,age)?}public void study(){System.out.println("學生學習")?} } class PersonDemo {public static void main(String[] args){//創(chuàng)建老師類對象并進行測試Teacher t1 = new Teacher()?t1.setName("林青霞")?t1.setAge(30)?System.out.println(t1.getName() + "," + t1.getAge())?t1.teach()?Teacher t2 = new Teacher("風清揚", 33)?System.out.println(t2.getName() + "," + t2.getAge())?t2.teach()?// 創(chuàng)建學生類對象測試Student s = new Student("張三",23);System.out.println(s.getName() + "," + s.getAge())?s.study()?} }5、修飾符
1、權限修飾符:
2、final:
fianl關鍵字的作用:
- final代表最終的意思,可以修飾成員方法,成員變量,類。
final修飾類、方法、變量的效果:
- fianl修飾類:該類不能被繼承(不能有子類,但是可以有父類)。
- final修飾方法:該方法不能被重寫。
- final修飾變量:表明該變量是一個常量,不能再次賦值。
3、static:
static的概念:
- static關鍵字是靜態(tài)的意思,可以修飾【成員方法】,【成員變量】。
static修飾的特點:
4、static訪問特點:
- 靜態(tài)成員方法只能訪問靜態(tài)成員【方法或變量】。
main方法是靜態(tài)的。
6、多態(tài)
1、什么是多態(tài)?
- 同一個對象,在不同時刻表現(xiàn)出來的不同形態(tài)。
2、多態(tài)的前提:
3、多態(tài)中的成員訪問特點:
成員變量:
- 編譯看父類,運行看父類
成員方法:
- 編譯看父類,運行看子類
4、多態(tài)的好處和弊端:
好處:
- 提高程序的擴展性。定義方法時候,使用父類型作為參數(shù),在使用的時候,使用具體的子類型參與操作。
弊端:
- 不能使用子類的特有成員。
5、多態(tài)中的轉型:
向上轉型:
- 父類引用指向子類對象
向下轉型:
- 格式:子類型 對象名 = (子類型)父類引用;
例:
- 動物類:
- 貓類:
- 測試類:
7、抽象類
1、抽象類的概述:
- 當在做子類共性功能抽取時,有些方法在父類中并沒有具體的體現(xiàn),這個時候就需要抽象類了!
- 在Java中,一個沒有方法體的方法應該定義為抽象方法,而類中如果有抽象方法,該類必須定義為抽象類!
2、抽象類的特點:
1、抽象類和抽象方法必須使用 abstract 關鍵字修飾。
//抽象類的定義public abstract class 類名 {//抽象方法的定義public abstract void eat()? }2、抽象類中不一定有抽象方法,有抽象方法的類一定是抽象類。
3、抽象類不能實例化
- 抽象類如何實例化呢?參照多態(tài)的方式,通過子類對象實例化,這叫抽象類多態(tài)。
4、抽象類的子類
- 要么重寫抽象類中的所有抽象方法
- 要么是抽象類
3、抽象類的成員特點:
成員變量:
- 既可以是變量
- 也可以是常量
構造方法:
- 空參構造
- 有參構造
成員方法:
- 抽象方法
- 普通方法
8、接口
1、接口的概述:
- 接口就是一種公共的規(guī)范標準,只要符合規(guī)范標準,大家都可以通用。
- Java中的接口更多的體現(xiàn)在對行為的抽象!
2、接口的特點:
1、接口用關鍵字interface修飾
public interface 接口名 {}2、類實現(xiàn)接口用implements表示
public class 類名 implements 接口名 {}3、接口不能實例化
- 接口如何實例化呢?參照多態(tài)的方式,通過實現(xiàn)類對象實例化,這叫接口多態(tài)。
4、 多態(tài)的形式:具體類多態(tài),抽象類多態(tài),接口多態(tài)。
5、接口的子類
- 要么重寫接口中的所有抽象方法
- 要么子類也是抽象類
3、抽象類的成員特點:
成員變量:只能是常量且為靜態(tài); 默認修飾符:public static final
構造方法:沒有,因為接口主要是擴展功能的,而沒有具體存在。
成員方法:只能是抽象方法。默認修飾符:public abstract
9、內(nèi)部類
1、內(nèi)部類的基本使用:
1.內(nèi)部類概念:
- 在一個類中定義一個類。舉例:在一個類A的內(nèi)部定義一個類B,類B就被稱為內(nèi)部類。
例:
class Outer {public class Inner {} }2、內(nèi)部類的訪問特點:
- 內(nèi)部類可以直接訪問外部類的成員,包括私有
- 外部類要訪問內(nèi)部類的成員,必須創(chuàng)建對象
示例代碼:
/*內(nèi)部類訪問特點:內(nèi)部類可以直接訪問外部類的成員,包括私有外部類要訪問內(nèi)部類的成員,必須創(chuàng)建對象 */ public class Outer {private int num = 10?public class Inner {public void show() {System.out.println(num)?}}public void method() {Inner i = new Inner()?i.show()?} }2、成員內(nèi)部類:
1.成員內(nèi)部類的定義位置:
- 在類中方法,跟成員變量是一個位置
2.外界創(chuàng)建成員內(nèi)部類格式:
- 格式:外部類名.內(nèi)部類名 對象名 = 外部類對象.內(nèi)部類對象;
- 舉例:Outer.Inner oi = new Outer().new Inner();
3.成員內(nèi)部類的推薦使用方案:
- 將一個類,設計為內(nèi)部類的目的,大多數(shù)都是不想讓外界去訪問,所以內(nèi)部類的定義應該私有化,私有化之后,再提供一個可以讓外界調(diào)用的方法,方法內(nèi)部創(chuàng)建內(nèi)部類對象并調(diào)用。
3、局部內(nèi)部類:
1.局部內(nèi)部類定義位置:
- 局部內(nèi)部類是在方法中定義的類
2.局部內(nèi)部類方式方式
- 局部內(nèi)部類,外界是無法直接使用,需要在方法內(nèi)部創(chuàng)建對象并使用。
- 該類可以直接訪問外部類的成員,也可以訪問方法內(nèi)的局部變量。
示例代碼:
class Outer {private int num = 10?public void method() {int num2 = 20?class Inner {public void show() {System.out.println(num)?System.out.println(num2)?}}Inner i = new Inner()?i.show()?} } public class OuterDemo {public static void main(String[] args) {Outer o = new Outer()?o.method()?} }4、 匿名內(nèi)部類 (局部內(nèi)部類的一種):
匿名內(nèi)部類的前提:
- 存在一個類或者接口,這里的類可以是具體類也可以是抽象類。
匿名內(nèi)部類的格式:
-
new 類名 ( ) {
重寫方法
} -
new 接口名 ( ) {
重寫方法
}
舉例:
new Inter(){@Overridepublic void method(){} };匿名內(nèi)部類的本質(zhì):
- 本質(zhì):是一個繼承了該類或者實現(xiàn)了該接口的子類匿名對象。
匿名內(nèi)部類直接調(diào)用方法:
接口:
interface Inter{void method()? } class Test{public static void main(String[] args){new Inter(){@Overridepublic void method(){System.out.println("我是匿名內(nèi)部類")?}}.method()? // 直接調(diào)用方法} }匿名內(nèi)部類的細節(jié):
- 匿名內(nèi)部類可以通過多態(tài)的形式接受。
匿名內(nèi)部類在開發(fā)中的使用:
- 當發(fā)現(xiàn)某個方法需要,接口或抽象類的子類對象,我們就可以傳遞一個匿名內(nèi)部類過去,來簡化傳統(tǒng)的代碼
示例代碼:
接口:
interface Jumpping {void jump()? }實現(xiàn)類1:
class Cat implements Jumpping {@Overridepublic void jump() {System.out.println("貓可以跳高了")?} }實現(xiàn)類2:
class Dog implements Jumpping {@Overridepublic void jump() {System.out.println("狗可以跳高了")?} }操作類:
class JumppingOperator {public void method(Jumpping j) { //new Cat()? new Dog()?j.jump()?} }測試類:
class JumppingDemo {public static void main(String[] args) {//需求:創(chuàng)建接口操作類的對象,調(diào)用method方法JumppingOperator jo = new JumppingOperator()?Jumpping j = new Cat()?jo.method(j)?Jumpping j2 = new Dog()?jo.method(j2)?System.out.println("--------")?// 匿名內(nèi)部類的簡化jo.method(new Jumpping() {@Overridepublic void jump() {System.out.println("貓可以跳高了")?}})?// 匿名內(nèi)部類的簡化jo.method(new Jumpping() {@Overridepublic void jump() {System.out.println("狗可以跳高了")?}})?} }9、包裝類
1、基本類型包裝類:
-
基本類型包裝類的作用:將基本數(shù)據(jù)類型封裝成對象的好處在于可以在對象中定義更多的功能方法操作該數(shù)據(jù)。
-
常用的操作之一:用于基本數(shù)據(jù)類型與字符串之間的轉換。
基本類型對應的包裝類:
1.2、int和String類型的相互轉換:
1、int轉換為String:
轉換方式:
- 方式一:直接在數(shù)字后加一個空字符串
- 方式二:通過String類靜態(tài)方法valueOf()
例:
public class IntegerDemo {public static void main(String[] args) {//int --- Stringint number = 100;//方式1String s1 = number + "";System.out.println(s1);//方式2//public static String valueOf(int i)String s2 = String.valueOf(number);System.out.println(s2);System.out.println("--------");} }2、String轉換為int:
轉換方式:
- 方式一:先將字符串數(shù)字轉成Integer,再調(diào)用valueOf()方法。
- 方式二:通過Integer靜態(tài)方法parseInt()進行轉換。
例:
public class IntegerDemo {public static void main(String[] args) {//String --- intString s = "100";//方式1:String --- Integer --- intInteger i = Integer.valueOf(s);//public int intValue()int x = i.intValue();System.out.println(x);//方式2//public static int parseInt(String s)int y = Integer.parseInt(s);System.out.println(y);} }3、自動拆箱和自動裝箱:
自動裝箱:
- 把基本數(shù)據(jù)類型轉換為對應的包裝類類型
自動拆箱:
- 把包裝類類型轉換為對應的基本數(shù)據(jù)類型
示例代碼:
Integer i = 100; // 自動裝箱i += 200; // i = i + 200; i + 200 自動拆箱;i = i + 200; 是自動裝箱10、時間日期類
1、 SimpleDateFormat類:
SimpleDateFormat類構造方法:
SimpleDateFormat類的常用方法:
-
格式化(從Date到String):public final String format(Date date):將日期格式化成日期/時間字符串。
-
解析(從String到Date):public Date parse(String source):從給定字符串的開始解析文本以生成日期。
例:
public class SimpleDateFormatDemo {public static void main(String[] args) throws ParseException {//格式化:從 Date 到 StringDate d = new Date(); // SimpleDateFormat sdf = new SimpleDateFormat();SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");String s = sdf.format(d);System.out.println(s);System.out.println("--------");//從 String 到 DateString ss = "2048-08-09 11:11:11";//ParseExceptionSimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date dd = sdf2.parse(ss);System.out.println(dd);} }運行結果:
11、異常
1、異常:
異常的概述:
- 異常就是程序出現(xiàn)了不正常的情況。
異常的體系結構:
Error :嚴重問題,不需要處理。
Exception:稱為異常類,它表示程序本身可以處理的問題。
- RuntimeException:在編譯期是不檢查的,出現(xiàn)問題后,需要我們回來修改代碼。
- 非RuntimeException:編譯期就必須處理的,否則程序不能通過編譯,就更不能正常運行了。
2、Throwable成員方法:
常用方法:
例:
3、編譯時異常和運行時異常的區(qū)別:
編譯時異常:
- 都是Exception類及其子類
- 必須顯示處理,否則程序就會發(fā)生錯誤,無法通過編譯
運行時異常:
- 都是RuntimeException類及其子類
- 無需顯示處理,也可以和編譯時異常一樣處理
4、throws方式處理異常:
格式:
public void 方法() throws 異常類名 {}注意事項:
示例代碼:
public class ExceptionDemo {public static void main(String[] args) {System.out.println("開始"); // method();try { //誰調(diào)用誰處理method2();}catch (ParseException e) {e.printStackTrace();}System.out.println("結束");}//編譯時異常public static void method2() throws ParseException {String s = "2048-08-09";SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date d = sdf.parse(s);System.out.println(d); }//運行時異常 可拋可不拋public static void method() throws ArrayIndexOutOfBoundsException {int[] arr = {1, 2, 3};System.out.println(arr[3]);} }5、自定義異常:
例:
- 自定義異常類:
- 老師類:
- 測試類:
12、Collection集合
1、集合體系結構:
集合類的特點:
- 提供一種存儲空間可變的存儲模型,存儲的數(shù)據(jù)容量可以隨時發(fā)生改變
集合類的體系圖:
其中:
- List 為有序可重復的,
- Set 為無序不可重復的。
2、Collection集合概述和基本使用:
Collection集合概述:
- 是單例集合的頂層接口,它表示一組對象,這些對象也稱為Collection的元素。
- JDK 不提供此接口的任何直接實現(xiàn),它提供更具體的子接口(如Set和List)實現(xiàn)。
Collection集合的常用方法:
Collection集合基本使用:
運行結果:
其中ArrayList重寫了toString方法,直接輸出了集合添加的內(nèi)容。
3、Collection集合的遍歷:
lterator:迭代器,集合的專用遍歷方式
- Iterator <E> iterator():返回此集合中元素的迭代器,通過集合的iterator()方法得到
- 迭代器是通過集合的iterator()方法得到的,所以我們說它是依賴于集合而存在的
lterator中的常用方法:
- E next():返回迭代中的下一個元素
- boolean hasNext():如果迭代具有更多元素,則返回true
示例代碼:
public class IteratorDemo {public static void main(String[] args) {//創(chuàng)建集合對象Collection<String> c = new ArrayList<>();//添加元素c.add("hello");c.add("world");c.add("java");c.add("javaee");//Iterator<E> iterator():返回此集合中元素的迭代器,通過集合的iterator()方法得到Iterator<String> it = c.iterator();//用while循環(huán)改進元素的判斷和獲取while (it.hasNext()) {String s = it.next();System.out.println(s);}} }輸出結果:
13、List集合
1、List集合概述和特點:
List集合概述:
- 有序集合(也稱為序列),用戶可以精確控制列表中每個元素的插入位置。用戶可以通過整數(shù)索引訪問元素,并搜索列表中的元素。
- 與Set集合不同,列表通常允許重復的元素。
List集合特點:
2、List集合的特有方法:
3、并發(fā)修改異常:
出現(xiàn)的原因:
- 迭代器遍歷的過程中,通過集合對象修改了集合中的元素,造成了迭代器獲取元素中判斷預期修改值和實際修改值不一致,則會出現(xiàn):ConcurrentModificationException
解決的方案:
- 用for循環(huán)遍歷,然后用集合對象做對應的操作即可。
示例代碼:
public class ListDemo {public static void main(String[] args) {//創(chuàng)建集合對象List<String> list = new ArrayList<String>();//添加元素list.add("hello");list.add("world");list.add("java");//遍歷集合,得到每一個元素,看有沒有"world"這個元素,如果有,我就添加一個"javaee"元素,請寫代碼實現(xiàn) // Iterator<String> it = list.iterator(); // while (it.hasNext()) { // String s = it.next(); // if(s.equals("world")) { // list.add("javaee"); // } // }for(int i=0; i<list.size(); i++) {String s = list.get(i);if(s.equals("world")) {list.add("javaee");}}//輸出集合對象System.out.println(list);} }4、列表迭代器:
ListIterator介紹:
- 通過List集合的listIterator()方法得到,所以說它是List集合特有的迭代器。
- 用于允許程序員沿任一方向遍歷的列表迭代器,在迭代期間修改列表,并獲取列表中迭代器的當前位置。
示例代碼:
public class ListIteratorDemo {public static void main(String[] args) {//創(chuàng)建集合對象List<String> list = new ArrayList<String>();//添加元素list.add("hello");list.add("world");list.add("java");//獲取列表迭代器ListIterator<String> lit = list.listIterator();while (lit.hasNext()) {String s = lit.next();if(s.equals("world")) {lit.add("javaee");}}System.out.println(list);} }5、增強for循環(huán):
增強for目的:簡化數(shù)組和Collection集合的遍歷
- 實現(xiàn)lterable接口的類允許其對象成為增強型for語句的目標。
- 它是JDK5之后出現(xiàn)的,其內(nèi)部原理是一個lterator迭代器。
格式:
for(元素數(shù)據(jù)類型 變量名 : 數(shù)組/集合對象名) {循環(huán)體;}示例代碼:
public class ForDemo {public static void main(String[] args) {int[] arr = {1,2,3,4,5};for(int i : arr) {System.out.println(i);}System.out.println("--------");String[] strArray = {"hello","world","java"};for(String s : strArray) {System.out.println(s);}System.out.println("--------");List<String> list = new ArrayList<String>();list.add("hello");list.add("world");list.add("java");for(String s : list) {System.out.println(s);}System.out.println("--------");//內(nèi)部原理是一個Iterator迭代器/*for(String s : list) {if(s.equals("world")) {list.add("javaee"); //ConcurrentModificationException}}*/} }14、List集合的實現(xiàn)類
1、數(shù)據(jù)結構之數(shù)組和鏈表:
數(shù)組結構:
- 查詢快、增刪慢
隊列結構
- 查詢慢、增刪快
2、List集合子類的特點:
List集合常用子類:ArrayList,LinkedList
- ArrayList:底層數(shù)據(jù)結構是數(shù)組,查詢快,增刪慢
- LinkedList:底層數(shù)據(jù)結構是鏈表,查詢慢,增刪快
3、LinkedList集合的特有功能:
特有方法:
15、Set集合
1、Set集合特點:
- 不包含重復元素的集合
- 沒有帶索引的方法,所以不能使用普通for循環(huán)遍歷
2、哈希值:
哈希值簡介:
- 是JDK根據(jù)對象的地址或者字符串或者數(shù)字算出來的int類型的數(shù)值。
如何獲取哈希值:
- Object類中的public int hashCode():返回對象的哈希碼值。
哈希值的特點:
- 同一個對象多次調(diào)用hashCode()方法返回的哈希值是相同的。
- 默認情況下,不同對象的哈希值是不同的。而重寫hashCode()方法,可以實現(xiàn)讓不同對象的哈希值相同。
3、HashSet集合概述和特點:
HashSet集合的特點:
- 底層數(shù)據(jù)結構是哈希表
- 對集合的迭代順序不作任何保證,也就是說不保證存儲和取出的元素順序一致
- 沒有帶索引的方法,所以不能使用普通for循環(huán)遍歷
- 由于是Set集合,所以是不包含重復元素的集合
HashSet集合的基本使用:
public class HashSetDemo01 {public static void main(String[] args) {//創(chuàng)建集合對象HashSet<String> hs = new HashSet<String>();//添加元素hs.add("hello");hs.add("world");hs.add("java");hs.add("world");//遍歷for(String s : hs) {System.out.println(s);}} }運行結果:
4、HashSet集合存儲學生對象并遍歷:
案例需求 :
- 創(chuàng)建一個存儲學生對象的集合,存儲多個學生對象,使用程序實現(xiàn)在控制臺遍歷該集合。
- 要求:學生對象的成員變量值相同,我們就認為是同一個對象。
代碼實現(xiàn):
- 學生類
- 測試類:
16、Set集合排序
1、TreeSet集合概述和特點:
TreeSet集合概述:
?????????TreeSet():根據(jù)其元素的自然排序進行排序。
?????????TreeSet(Comparator comparator) :根據(jù)指定的比較器進行排序。
TreeSet集合基本使用:
public class TreeSetDemo01 {public static void main(String[] args) {//創(chuàng)建集合對象TreeSet<Integer> ts = new TreeSet<Integer>();//添加元素ts.add(10);ts.add(40);ts.add(30);ts.add(50);ts.add(20);ts.add(30);//遍歷集合for(Integer i : ts) {System.out.println(i);}} }運行結果:
2、自然排序Comparable:
案例需求:
- 存儲學生對象并遍歷,創(chuàng)建TreeSet集合使用帶參構造方法
- 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序
代碼實現(xiàn):
- 學生類:
- 測試類:
3、比較器排序Comparator:
案例需求:
- 存儲學生對象并遍歷,創(chuàng)建TreeSet集合使用帶參構造方法。
- 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序。
代碼實現(xiàn):
- 學生類:
- 測試類
17、泛型
1、泛型類:
定義格式:
修飾符 class 類名<類型> { }此處T可以隨便寫為任意標識,常見的如T、E、K、V等形式的參數(shù)常用于表示泛型
示例代碼:
泛型類:
public class Generic<T> {private T t;public T getT() {return t;}public void setT(T t) {this.t = t;} }測試類:
public class GenericDemo {public static void main(String[] args) {Generic<String> g1 = new Generic<String>();g1.setT("林青霞");System.out.println(g1.getT());Generic<Integer> g2 = new Generic<Integer>();g2.setT(30);System.out.println(g2.getT());Generic<Boolean> g3 = new Generic<Boolean>();g3.setT(true);System.out.println(g3.getT());} }2、泛型方法:
定義格式:
修飾符 <類型> 返回值類型 方法名(類型 變量名) { }示例代碼:
帶有泛型方法的類:
public class Generic {public <T> void show(T t) {System.out.println(t);} }測試類:
public class GenericDemo {public static void main(String[] args) {Generic g = new Generic();g.show("林青霞");g.show(30);g.show(true);g.show(12.34);} }3、泛型接口:
定義格式:
修飾符 interface 接口名<類型> { }示例代碼:
泛型接口:
public interface Generic<T> {void show(T t); }泛型接口實現(xiàn)類:
public class GenericImpl<T> implements Generic<T> {@Overridepublic void show(T t) {System.out.println(t);} }測試類:
public class GenericDemo {public static void main(String[] args) {Generic<String> g1 = new GenericImpl<String>();g1.show("林青霞");Generic<Integer> g2 = new GenericImpl<Integer>();g2.show(30);} }18、可變參數(shù)
可變參數(shù)介紹:
- 可變參數(shù)又稱參數(shù)個數(shù)可變,用作方法的形參出現(xiàn),那么方法參數(shù)個數(shù)就是可變的了。
可變參數(shù)定義格式:
修飾符 返回值類型 方法名(數(shù)據(jù)類型… 變量名) { }可變參數(shù)的注意事項:
- 這里的變量其實是一個數(shù)組
- 如果一個方法有多個參數(shù),包含可變參數(shù),可變參數(shù)要放在最后
可變參數(shù)的基本使用:
19、Map集合
1、Map集合概述和特點:
Map集合概述:
interface Map<K,V> K:鍵的類型;V:值的類型Map集合的特點:
Map集合的基本使用:
public class MapDemo01 {public static void main(String[] args) {//創(chuàng)建集合對象Map<String,String> map = new HashMap<String,String>();//V put(K key, V value) 將指定的值與該映射中的指定鍵相關聯(lián)map.put("itheima001","林青霞");map.put("itheima002","張曼玉");map.put("itheima003","王祖賢");map.put("itheima003","柳巖");//鍵值相同時會覆蓋原來的元素//輸出集合對象System.out.println(map);} }運行結果:
2、Map集合的基本功能:
方法介紹:
3、Map集合的獲取功能:
4、Map集合的遍歷:
方式一:
步驟分析:
代碼實現(xiàn):
public class MapDemo01 {public static void main(String[] args) {//創(chuàng)建集合對象Map<String, String> map = new HashMap<String, String>();//添加元素map.put("張無忌", "趙敏");map.put("郭靖", "黃蓉");map.put("楊過", "小龍女");//獲取所有鍵的集合。用keySet()方法實現(xiàn)Set<String> keySet = map.keySet();//遍歷鍵的集合,獲取到每一個鍵。用增強for實現(xiàn)for (String key : keySet) {//根據(jù)鍵去找值。用get(Object key)方法實現(xiàn)String value = map.get(key);System.out.println(key + "," + value);}} }方式二:
步驟分析:
獲取所有鍵值對對象的集合
Set<Map.Entry<K,V>> entrySet():獲取所有鍵值對對象的集合
遍歷鍵值對對象的集合,得到每一個鍵值對對象
用增強for實現(xiàn),得到每一個Map.Entry
根據(jù)鍵值對對象獲取鍵和值
用getKey()得到鍵
用getValue()得到值
例:
public class MapDemo02 {public static void main(String[] args) {//創(chuàng)建集合對象Map<String, String> map = new HashMap<String, String>();//添加元素map.put("張無忌", "趙敏");map.put("郭靖", "黃蓉");map.put("楊過", "小龍女");//獲取所有鍵值對對象的集合Set<Map.Entry<String, String>> entrySet = map.entrySet();//遍歷鍵值對對象的集合,得到每一個鍵值對對象for (Map.Entry<String, String> me : entrySet) {//根據(jù)鍵值對對象獲取鍵和值String key = me.getKey();String value = me.getValue();System.out.println(key + "," + value);}} }20、Collections集合工具類
1、Collections概述和使用:
Collections類的作用:
- 是針對集合操作的工具類
Collections類常用方法:
21、File類
1、File類概述和構造方法:
File類介紹:
- 它是文件和目錄路徑名的抽象表示
- 文件和目錄可以通過File封裝成對象
- 對于File而言,其封裝的并不是一個真正存在的文件,僅僅是一個路徑名。它可以是存在的,也可以是不存在的。將來是要通過具體的操作把這個路徑的內(nèi)容轉換為具體存在的。
File類的構造方法:
示例代碼:
public class FileDemo01 {public static void main(String[] args) {//File(String pathname):通過將給定的路徑名字符串轉換為抽象路徑名來創(chuàng)建新的 File實例。File f1 = new File("E:\\itcast\\java.txt");System.out.println(f1);//File(String parent, String child):從父路徑名字符串和子路徑名字符串創(chuàng)建新的File實例。File f2 = new File("E:\\itcast","java.txt");System.out.println(f2);//File(File parent, String child):從父抽象路徑名和子路徑名字符串創(chuàng)建新的 File實例。File f3 = new File("E:\\itcast");File f4 = new File(f3,"java.txt");System.out.println(f4);} }其中File類重寫了toString方法。
運行結果:
2、File類創(chuàng)建功能:
方法分類:
示例代碼:
3、File類判斷和獲取功能:
判斷功能:
獲取功能:
4、File類刪除功能:
刪除目錄時的注意事項:
- 如果一個目錄中有內(nèi)容(目錄,文件),不能直接刪除。應該先刪除目錄中的內(nèi)容,最后才能刪除目錄
22、IO流
1、IO流的分類:
按照數(shù)據(jù)類型來分:
1.字節(jié)流:
- 字節(jié)輸入流
- 字節(jié)輸出流
2.字符流:
- 字符輸入流
- 字符輸出流
IO流的使用場景;
- 如果操作的是純文本文件,優(yōu)先使用字符流。
- 如果操作的是圖片、視頻、音頻等二進制文件。優(yōu)先使用字節(jié)流。
- 如果不確定文件類型,優(yōu)先使用字節(jié)流。字節(jié)流是萬能的流。
2、字節(jié)流寫數(shù)據(jù):
字節(jié)流抽象基類:
- InputStream:這個抽象類是表示字節(jié)輸入流的所有類的超類
- OutputStream:這個抽象類是表示字節(jié)輸出流的所有類的超類
子類名特點:子類名稱都是以其父類名作為子類名的后綴
字節(jié)輸出流:
- FileOutputStream(String name):創(chuàng)建文件輸出流以指定的名稱寫入文件。
使用字節(jié)輸出流寫數(shù)據(jù)的步驟:
示例代碼:
public class FileOutputStreamDemo01 {public static void main(String[] args) throws IOException {//創(chuàng)建字節(jié)輸出流對象//FileOutputStream(String name):創(chuàng)建文件輸出流以指定的名稱寫入文件FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");//void write(int b):將指定的字節(jié)寫入此文件輸出流fos.write(97);// fos.write(57);// fos.write(55);//最后都要釋放資源//void close():關閉此文件輸出流并釋放與此流相關聯(lián)的任何系統(tǒng)資源。fos.close();} }3、字節(jié)流寫數(shù)據(jù)的三種方式:
4、字節(jié)流寫數(shù)據(jù)加異常處理:
finally特點:
- 被finally控制的語句一定會執(zhí)行,除非JVM退出。
示例代碼:
public class FileOutputStreamDemo04 {public static void main(String[] args) {//加入finally來實現(xiàn)釋放資源FileOutputStream fos = null;//初始化,保證fos.close能執(zhí)行。try {fos = new FileOutputStream("myByteStream\\fos.txt");fos.write("hello".getBytes());} catch (IOException e) {e.printStackTrace();} finally {if(fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}} }5、字節(jié)流讀數(shù)據(jù):
1、一次讀一個字節(jié)數(shù)據(jù):
字節(jié)輸入流:
- FileInputStream(String name):通過打開與實際文件的連接來創(chuàng)建一個FileInputStream ,該文件由文件系統(tǒng)中的路徑名name命名。
示例代碼:
public class FileInputStreamDemo01 {public static void main(String[] args) throws IOException {//創(chuàng)建字節(jié)輸入流對象//FileInputStream(String name)FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");int by;/*fis.read():讀數(shù)據(jù)by=fis.read():把讀取到的數(shù)據(jù)賦值給byby != -1:判斷讀取到的數(shù)據(jù)是否是-1*/while ((by=fis.read())!=-1) {System.out.print((char)by);}//釋放資源fis.close();} }2、一次讀一個字節(jié)數(shù)組數(shù)據(jù):
一次讀一個字節(jié)數(shù)組的方法:
- public int read(byte[] b):從輸入流讀取最多b.length個字節(jié)的數(shù)據(jù)
示例代碼:
public class FileInputStreamDemo02 {public static void main(String[] args) throws IOException {//創(chuàng)建字節(jié)輸入流對象FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");/*hello\r\nworld\r\n第一次:hello第二次:\r\nwor第三次:ld\r\nr*/byte[] bys = new byte[1024]; //1024及其整數(shù)倍int len;while ((len=fis.read(bys))!=-1) {System.out.print(new String(bys,0,len));}//釋放資源fis.close();} }6、字節(jié)流復制文本文件:
案例需求
- 把“E:\itcast\窗里窗外.txt”復制到模塊目錄下的“窗里窗外.txt”
實現(xiàn)步驟:
-
復制文本文件,其實就把文本文件的內(nèi)容從一個文件中讀取出來(數(shù)據(jù)源),然后寫入到另一個文件中(目的地)
-
數(shù)據(jù)源::
E:\itcast\窗里窗外.txt — 讀數(shù)據(jù) — InputStream — FileInputStream -
目的地:
myByteStream\窗里窗外.txt — 寫數(shù)據(jù) — OutputStream — FileOutputStream
代碼實現(xiàn):
public class CopyTxtDemo {public static void main(String[] args) throws IOException {//根據(jù)數(shù)據(jù)源創(chuàng)建字節(jié)輸入流對象FileInputStream fis = new FileInputStream("E:\\itcast\\窗里窗外.txt");//根據(jù)目的地創(chuàng)建字節(jié)輸出流對象FileOutputStream fos = new FileOutputStream("myByteStream\\窗里窗外.txt");//讀寫數(shù)據(jù),復制文本文件(一次讀取一個字節(jié),一次寫入一個字節(jié))int by;while ((by=fis.read())!=-1) {fos.write(by);}//釋放資源fos.close();fis.close();} }7、字節(jié)流復制圖片:
案例需求:
- 把“E:\itcast\mn.jpg”復制到模塊目錄下的“mn.jpg”
實現(xiàn)步驟:
代碼實現(xiàn):
public class CopyJpgDemo {public static void main(String[] args) throws IOException {//根據(jù)數(shù)據(jù)源創(chuàng)建字節(jié)輸入流對象FileInputStream fis = new FileInputStream("E:\\itcast\\mn.jpg");//根據(jù)目的地創(chuàng)建字節(jié)輸出流對象FileOutputStream fos = new FileOutputStream("myByteStream\\mn.jpg");//讀寫數(shù)據(jù),復制圖片(一次讀取一個字節(jié)數(shù)組,一次寫入一個字節(jié)數(shù)組)byte[] bys = new byte[1024];int len;while ((len=fis.read(bys))!=-1) {fos.write(bys,0,len);}//釋放資源fos.close();fis.close();} }23、字節(jié)緩沖流
1、字節(jié)緩沖流構造方法:
字節(jié)緩沖流構造方法:
-
BufferOutputStream:該類實現(xiàn)緩沖輸出流。 通過設置這樣的輸出流,應用程序可以向底層輸出流寫入字節(jié),而不必為寫入的每個字節(jié)導致底層系統(tǒng)的調(diào)用。
-
BufferedInputStream:創(chuàng)建BufferedInputStream將創(chuàng)建一個內(nèi)部緩沖區(qū)數(shù)組。 當從流中讀取或跳過字節(jié)時,內(nèi)部緩沖區(qū)將根據(jù)需要從所包含的輸入流中重新填充,一次很多字節(jié)。
構造方法:
示例代碼:
24、字符流
1、為什么會出現(xiàn)字符流:
字符流的介紹:
- 由于字節(jié)流操作中文不是特別的方便,所以Java就提供字符流
字符流 = 字節(jié)流 + 編碼表
中文的字節(jié)存儲方式:
- 用字節(jié)流復制文本文件時,文本文件也會有中文,但是沒有問題,原因是最終底層操作會自動進行字節(jié)拼接成中文。
2、字符串中的編碼解碼問題:
相關方法:
代碼演示:
3、字符流中的編碼解碼問題:
字符流中和編碼解碼的兩個類:
-
InputStreamReader:是從字節(jié)流到字符流的橋梁,它讀取字節(jié),并使用指定的編碼將其解碼為字符
它使用的字符集可以由名稱指定,也可以接受平臺的默認字符集。 -
OutputStreamWriter:是從字符流到字節(jié)流的橋梁,使用指定的編碼將寫入的字符編碼為字節(jié)它使用的字符集可以由名稱指定,也可以接受平臺的默認字符集。
構造方法:
示例代碼:
4、字符流寫數(shù)據(jù)的5種方式:
方法介紹:
刷新和關閉的方法:
刷新流作用:刷新緩沖,寫入數(shù)據(jù)。
5、字符流讀數(shù)據(jù)的2種方式:
6、字符緩沖流:
構造方法:
7、字符緩沖流特有功能:
BufferedWriter:
寫一個換行符,由操作系統(tǒng)系統(tǒng)決定。
BufferedReader:
8、字符緩沖流特有功能復制Java文件:
代碼實現(xiàn):
public class CopyJavaDemo02 {public static void main(String[] args) throws IOException {//根據(jù)數(shù)據(jù)源創(chuàng)建字符緩沖輸入流對象BufferedReader br = new BufferedReader(new FileReader("myCharStream\\ConversionStreamDemo.java"));//根據(jù)目的地創(chuàng)建字符緩沖輸出流對象BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy.java"));//讀寫數(shù)據(jù),復制文件//使用字符緩沖流特有功能實現(xiàn)String line;while ((line=br.readLine())!=null) {bw.write(line);bw.newLine();//換行bw.flush();}//釋放資源bw.close();br.close();} }9、IO流小結:
字節(jié)流:
字節(jié)流可以復制任意文件數(shù)據(jù),一般采用字節(jié)緩沖流一次讀寫一個字節(jié)數(shù)組的方式
字符流:
字符流只能復制文本數(shù)據(jù),一般使用字符緩沖流。
25、IO特殊操作流
1、標準輸入流:
System 類中有兩個靜態(tài)的成員變量
-
public static final InputStream in:標準輸入流。通常該流對應于鍵盤輸入或由主機環(huán)境或用戶指定的另一個輸入源。(InputStream是返回值類型 in是方法,可以直接由類直接調(diào)用)
-
public static final PrintStream out:標準輸出流。通常該流對應于顯示輸出或由主機環(huán)境或用戶指定的另一個輸出目標。
自己實現(xiàn)鍵盤錄入數(shù)據(jù):
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));寫起來太麻煩,Java就提供了一個類實現(xiàn)鍵盤錄入:
Scanner sc = new Scanner(System.in);2、對象序列化流:
對象序列化介紹:
-
對象序列化:就是將對象保存到磁盤中,或者在網(wǎng)絡中傳輸對象;
-
這種機制就是使用一個字節(jié)序列表示一個對象,該字節(jié)序列包含:對象的類型、對象的數(shù)據(jù)和對象中存儲的屬性等信息。
-
字節(jié)序列寫到文件之后,相當于文件中持久保存了一個對象的信息;反之,該字節(jié)序列還可以從文件中讀取回來,重構對象,對它進行反序列化
對象序列化流: ObjectOutputStream
- 將Java對象的原始數(shù)據(jù)類型和圖形寫入OutputStream。 可以使用ObjectInputStream讀取(重構)對象。 可以通過使用流的文件來實現(xiàn)對象的持久存儲。 如果流是網(wǎng)絡套接字流,則可以在另一個主機上或另一個進程中重構對象。
構造方法:
序列化對象的方法:
示例代碼:
學生類
public class Student implements Serializable {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }測試類:
public class ObjectOutputStreamDemo {public static void main(String[] args) throws IOException {//ObjectOutputStream(OutputStream out):創(chuàng)建一個寫入指定的OutputStream的ObjectOutputStreamObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));//創(chuàng)建對象Student s = new Student("林青霞",30);//void writeObject(Object obj):將指定的對象寫入ObjectOutputStreamoos.writeObject(s);//釋放資源oos.close();} }注意事項:
3、對象反序列化流:
對象反序列化流: ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream編寫的原始數(shù)據(jù)和對象
構造方法:
反序列化對象的方法:
示例代碼:
26、多線程
1、進程和線程:
進程:是正在運行的程序
- 是系統(tǒng)進行資源分配和調(diào)用的獨立單位
- 每一個進程都有它自己的內(nèi)存空間和系統(tǒng)資源
線程:是進程中的單個順序控制流,是一條執(zhí)行路徑
- 單線程:一個進程如果只有一條執(zhí)行路徑,則稱為單線程程序
- 多線程:一個進程如果有多條執(zhí)行路徑,則稱為多線程程序
2、實現(xiàn)多線程方式一:繼承Thread類
方法介紹:
實現(xiàn)步驟:
例:
public class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(i);}} } public class ThreadTest {public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();//void start() 導致此線程開始執(zhí)行; Java虛擬機調(diào)用此線程的run方法my1.start();my2.start();} }兩個小問題:
為什么要重寫run()方法?
- 因為run()是用來封裝被線程執(zhí)行的代碼
run()方法和start()方法的區(qū)別?
- run():封裝線程執(zhí)行的代碼,直接調(diào)用,相當于普通方法的調(diào)用
- start():啟動線程;然后由JVM調(diào)用此線程的run()方法
3、設置和獲取線程名稱:
例:
獲取main方法的線程名
public class ThreadTest {public static void main(String[] args) {System.out.println(Thread.currentThread().getName());} }4、線程優(yōu)先級:
線程調(diào)度:
兩種調(diào)度方式
- 分時調(diào)度模型:所有線程輪流使用 CPU 的使用權,平均分配每個線程占用 CPU 的時間片。
- 搶占式調(diào)度模型:優(yōu)先讓優(yōu)先級高的線程使用 CPU,如果線程的優(yōu)先級相同,那么會隨機選擇一個,優(yōu)先級高的線程獲取的 CPU 時間片相對多一些。(Java使用的是搶占式調(diào)度模型)
優(yōu)先級相關方法:
默認優(yōu)先級為5
5、線程控制:
相關方法:
6、線程的生命周期:
7、實現(xiàn)多線程方式二:實現(xiàn)Runnable接口
Thread構造方法:
實現(xiàn)步驟:
例:
public class MyRunnable implements Runnable {@Overridepublic void run() {for(int i=0; i<100; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}} } public class MyRunnableDemo {public static void main(String[] args) {//創(chuàng)建MyRunnable類的對象MyRunnable my = new MyRunnable();//創(chuàng)建Thread類的對象,把MyRunnable對象作為構造方法的參數(shù)//Thread(Runnable target)// Thread t1 = new Thread(my);// Thread t2 = new Thread(my);//Thread(Runnable target, String name)Thread t1 = new Thread(my,"高鐵");Thread t2 = new Thread(my,"飛機");//啟動線程t1.start();t2.start();} }總結:
多線程的實現(xiàn)方案有兩種:
- 繼承Thread類
- 實現(xiàn)Runnable接口
相比繼承Thread類,實現(xiàn)Runnable接口的好處:
- 避免了Java單繼承的局限性
- 適合多個相同程序的代碼去處理同一個資源的情況,把線程和程序的代碼、數(shù)據(jù)有效分離,較好的體現(xiàn)了面向對象的設計思想。
🆗,關于java的基礎知識總結就到這里了,后面會接著學習Java EE 的 SpringMVC+Mybates框架。
總結
以上是生活随笔為你收集整理的Java SE 重点知识笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSP动作和内置对象
- 下一篇: Java——多线程学习