Java的三大平臺(tái)
JavaSE Java的標(biāo)準(zhǔn)平臺(tái):包含了Java的基礎(chǔ)的功能舶掖,學(xué)習(xí)的語法扶平,內(nèi)置的API方法
JavaEE Java的企業(yè)級(jí)應(yīng)用平臺(tái):JavaSE的基礎(chǔ)上据块,擴(kuò)展了一些API遇伞,用于B/S結(jié)構(gòu)的企業(yè)應(yīng)用的開發(fā)
JavaME Java的移動(dòng)應(yīng)用平臺(tái):JavaSE縮微版励负,給嵌入式系統(tǒng)或移動(dòng)端系統(tǒng)使用過時(shí)
Java語言特點(diǎn)
1.跨平臺(tái) 平臺(tái)-操作系統(tǒng)
任何平臺(tái)上編寫的Java程序侍郭,可以在另外的平臺(tái)上執(zhí)行
JDK Java的開發(fā)環(huán)境
JRE Java的運(yùn)行環(huán)境 - Java虛擬機(jī)
java文件 ->(編譯) class文件 -> Java虛擬機(jī)中運(yùn)行
2.面向?qū)ο? 以人類正常思維開發(fā)和設(shè)計(jì)軟件,開發(fā)程序開發(fā)方法:支撐大型的關(guān)系復(fù)雜系統(tǒng)的構(gòu)建
3.多線程:支持多任務(wù)場(chǎng)景
4.分布式:支持網(wǎng)絡(luò)應(yīng)用
5.簡(jiǎn)單:比C++簡(jiǎn)單 指針齿尽,回收(內(nèi)存泄露)Java中沒有指針沽损, 系統(tǒng)自動(dòng)回收
public class Demo1 {類塊 ,類中的代碼都要寫在類塊之中
public class Java中的關(guān)鍵字
主程序(main方法) :一個(gè)Java程序需要執(zhí)行循头,必須有一個(gè)main方法
mian方法是程序的入口绵估,需要程序執(zhí)行的代碼,一定要經(jīng)過main方法
public static void main(String[] args) {方法塊
System.out.println("中文");
Java程序之后的輸出語句
System.out.println(123);
寫完一行代碼后卡骂,編譯區(qū)出現(xiàn)紅叉(報(bào)錯(cuò)) 国裳,表示代碼的寫法已經(jīng)
違反了Java的語法規(guī)則
System.out.println(123);
System.out.print("中文");不換行輸出
}
變量:用于存儲(chǔ)程序在計(jì)算過程中用到數(shù)據(jù)
public class Demo1 {
錯(cuò)誤演示,不能存在相同的變量名
int a=5;
int a=4;
public static void main(String[] args) {
// TODO Auto-generated method stub
在Java中規(guī)定,變量需要先聲明 (int a)
并且對(duì)變量進(jìn)行初始化(對(duì)變量設(shè)置初始值),之后才可以正確使用
聲明了一個(gè)變量 a , 變量a的值是5
int a=5;
int a=6; 錯(cuò)誤演示偿警,不能同時(shí)存在相同的變量名
使用輸出語句打印一個(gè)變量時(shí)躏救,實(shí)際的輸出內(nèi)容是變量所指代數(shù)據(jù)值
System.out.println(a);結(jié)果是5
變量所指代的數(shù)據(jù)值可以改變,也就是可以對(duì)變量進(jìn)行重新賦值
a=6;
System.out.println(a); 結(jié)果是6
變量只需要聲明一次即可在一個(gè)塊內(nèi)(方法塊螟蒸,類塊)
不能同時(shí)出現(xiàn)多個(gè)相同名字的變量
變量的命名:
可以由字母盒使,數(shù)字,”_”和“$”組成七嫌。
不能以數(shù)字開頭少办,區(qū)分大小寫,不能使用java的關(guān)鍵字和保留字
可以使用中文命名但不建議使用诵原。
1.見名知意
int age=12;
int month=12;
2.駝峰命名法:如何變量名由多個(gè)英文單詞組成
從第二個(gè)單詞開始 每個(gè)單詞首字母大寫
int className=12;
int 年齡=5;//中文可以作為變量名英妓,但是不建議使用
System.out.println(123456879*987654321);
int num1=123456879;
int num2=987654321;
System.out.println(num1*num2);
int class=5; Java中的關(guān)鍵字和保留字不能作為變量名
int class=2; 錯(cuò)誤演示
}
}
數(shù)據(jù)類型
基本數(shù)據(jù)類型
整型
byte 占1個(gè)字節(jié)(一個(gè)字節(jié)占8位)-128-127
short 占2個(gè)字節(jié) -2^15 - (2^15-1)
int 占4個(gè)字節(jié) -2^31 - (2^31-1)
long 占8個(gè)字節(jié) -2^63 - (2^63-1)
浮點(diǎn)型
float 占4個(gè)字節(jié) 單精度
double 占8個(gè)字節(jié) 雙精度
字符型
char
布爾型
boolean
public static void main(String[] args) {
// TODO Auto-generated method stub
byte b=127; 聲明byte類型變量 b 值為127
short s=255; 聲明short類型變量 s 值為255
int i=1000; 聲明int類型變量 i 值為1000
在Java程序中直接書寫的整數(shù)值 (整數(shù)直接量),默認(rèn)為int類型
如果需要聲明數(shù)據(jù)為long類型挽放,在數(shù)據(jù)的末尾加上 L/l
long l=154L;
double數(shù)據(jù)類型比float數(shù)據(jù);類型更加精確
float f=5.2F; 單精度
double d=5.2; 雙精度
值寫在' ' 中蔓纠,只能有一個(gè)字符
char c='中';
System.out.println(c+1);
boolean b1=true;
boolean b2=false;
}
基本數(shù)據(jù)類型轉(zhuǎn)換
1.隱式轉(zhuǎn)換(自動(dòng)轉(zhuǎn)換)
小的數(shù)據(jù)類型可以自動(dòng)轉(zhuǎn)換到大的數(shù)據(jù)類型
2.強(qiáng)制轉(zhuǎn)換
大的數(shù)據(jù)類型轉(zhuǎn)換到小的數(shù)據(jù)類型
目標(biāo)數(shù)據(jù)類型 變量名=(目標(biāo)數(shù)據(jù)類型) 需要轉(zhuǎn)換的變量或者值辑畦;
int i=5;
byte b=(byte) i;
在Java程序中直接書寫的整數(shù)值 (整數(shù)直接量),默認(rèn)為int類型
Java允許將整數(shù)直接量賦值給 byte ,short,char,不超出數(shù)據(jù)類型的取值范圍即可
byte b=20;
System.out.println(b); 結(jié)果20
char c=25;
short s=22;
變量b是byte類型屬于隱式轉(zhuǎn)換,Java自動(dòng)執(zhí)行
int i=b;
System.out.println(i); 輸出結(jié)果20
* 由于i1是int類型 ,將i1賦值給byte類型的變量 b1
* 屬于 將大的數(shù)據(jù)類型轉(zhuǎn)為小的的數(shù)據(jù) Java中不允許直接操作
* 所有會(huì)出現(xiàn)編譯報(bào)錯(cuò)腿倚,因?yàn)樽兞縤1 不是整數(shù)直接量
byte b1=5;
int i1=12;
b1=i1;*/
byte ,short,char在參與運(yùn)算時(shí)纯出,會(huì)先轉(zhuǎn)換為int
byte bt1=10;
bt1=bt1+5; int - > byte 大的數(shù)據(jù)類型轉(zhuǎn)為小的數(shù)據(jù)類型, 編譯報(bào)錯(cuò)
強(qiáng)制轉(zhuǎn)換
int i=5;
byte b=(byte)i;
System.out.println(b);
double d=10;
System.out.println(d);
//進(jìn)行強(qiáng)制轉(zhuǎn)換敷燎,可能造成數(shù)據(jù)精度的缺失
int i1=(int)5.9;
System.out.println(i1);
System.out.println(1-0.1);
public static void main(String[] args) {
// TODO Auto-generated method stub
int a=5;
System.out.println(a);
a=10;
System.out.println(a);
* 聲明int類型變量i1叛薯,無初始化
* 聲明int類型變量i2搓彻,初始值10
* 所以,直接使用變量i1會(huì)編譯報(bào)錯(cuò)
int i1,i2=10;
System.out.println(i1); 會(huì)出現(xiàn)編譯報(bào)錯(cuò)
System.out.println(i2);
}
Java中的運(yùn)算符
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(12*25);
Java中變量也可以進(jìn)行運(yùn)算
int n=9;
int m=2;
System.out.println(n+m);//11
System.out.println(n-m);//7
System.out.println(n*m);//18
如果參與除法運(yùn)算的變量都是int類型,則其結(jié)果也是hint
System.out.println(n/m);//4
如果參與除法運(yùn)算的兩個(gè)變量類型不一致
其結(jié)果以大的數(shù)據(jù)類型為準(zhǔn)
int a=3;
double b=9;
System.out.println(b/a);//3.0
求余結(jié)果的正負(fù) 取決于第一個(gè)數(shù)的正負(fù)
System.out.println(5%2);//1
System.out.println(5%-2);//1
System.out.println(-5%2);//-1
System.out.println(-5%-2);//-1
}
public static void main(String[] args) {
// TODO Auto-generated method stub
++ ,-- 自增候衍,自減運(yùn)算符
* 如果 int i=5; ++i 表示 在i初始值的基礎(chǔ)上+1
* ++i 相當(dāng)于 i=i+1;
int i=5;
System.out.println(i);//5
++i;
System.out.println(i);//6
int n=2;
int m=3;
* 前置 ++ :
* int n=2; 如果使用++n (在輸出語句中臭埋,在運(yùn)算表達(dá)式中都表示使用)
* 這種情況下蛇捌,++n的值為 初始值+1
System.out.println((++n)+(++m));//7
System.out.println(n);//3
System.out.println(m);//4
* 后置 ++ :
* 如果使用n++(在輸出語句中毕贼,在運(yùn)算表達(dá)式中都表示使用)
* 這種情況下,n++的值為 n的原始值 拄衰,但是之后再使用n時(shí)卫漫,n的值是+1后的結(jié)果
System.out.println(n++);//2
System.out.println(n+1);//4
}
+=的特殊情況
public static void main(String[] args) {
// TODO Auto-generated method stub
int n=2;
n+=5; 表示 n=n+5;
System.out.println(n);
int m=10;
m%=4;m=m%4;
System.out.println(m);
byte b=2; b=b+1; 會(huì)編譯報(bào)錯(cuò)
b+=1;該情況不會(huì)出現(xiàn)編譯報(bào)錯(cuò) ,Java自動(dòng)執(zhí)行了強(qiáng)制轉(zhuǎn)換
}
比較運(yùn)算符
public static void main(String[] args) {
// TODO Auto-generated method stub
比較運(yùn)算符:比較兩個(gè)數(shù)值或者變量之間的大小關(guān)系
int n=5;
int m=4;
int k=4;
邏輯表達(dá)式:比較兩個(gè)或者多個(gè)變量之間的關(guān)系算式
邏輯表達(dá)式的結(jié)果為boolean - true(成立) , false(不成立)
System.out.println(n>m);//true
System.out.println(n<m);//fasle
System.out.println(n>=m);//true
System.out.println(n<=m);//false
System.out.println(n!=m);//true
System.out.println(n==m);//fasle
System.out.println(m==k);//true
}
邏輯運(yùn)算符
public static void main(String[] args) {
// TODO Auto-generated method stub
邏輯運(yùn)算符
邏輯與 &&
&&左右兩邊的表達(dá)式同時(shí)成立肾砂,整個(gè)表達(dá)式才成立
int a=5;
int b=10;
System.out.println(a<b&&b>12);//false
System.out.println(a<b&&b>5);//true
邏輯或 ||
||左右兩邊的表達(dá)式列赎,只要有一端成立,整個(gè)表達(dá)式就成立
如果||兩端的表達(dá)式都不成立镐确。則整個(gè)表達(dá)式不成立
int a1=12;
int b1=20;
System.out.println(a1<=20||b1>100);//true
System.out.println(a1>=20||b1>100);//false
邏輯非 !
對(duì)邏輯表達(dá)式的結(jié)果取相反的結(jié)果
System.out.println(a1>b1);//fasle
System.out.println(!(a1>b1));//true
System.out.println(!true);//fasle
}
短路問題
* 對(duì)于&&來說包吝,如果左邊的條件表達(dá)式結(jié)果明確為fasle
* java編譯器則不會(huì)再執(zhí)行&&右邊的條件表達(dá)式代碼
* 對(duì)于||來說,如果左邊的條件表達(dá)式結(jié)果明確為true
* java編譯器則不會(huì)再執(zhí)行||右邊的條件表達(dá)式代碼
int a=10;
int b=15;
System.out.println(++a<10&&++b>10);//false
System.out.println(a);//11
System.out.println(b);結(jié)果15 由于&&短路問題 ++b沒有被執(zhí)行 源葫,結(jié)果仍是15
字符串拼接
public static void main(String[] args) {
// TODO Auto-generated method stub
引用數(shù)據(jù)類型
String 字符串 String str="hello";
String str="hello1";
System.out.println(str);
* 當(dāng)+(加號(hào))的左邊或者右邊出現(xiàn)字符串時(shí)(String ,"")
* 則加號(hào)不再是加法運(yùn)算的功能诗越,而是字符串拼接功能
int n=10;
int m=5;
System.out.println("n="+n);此時(shí)加號(hào)將雙引號(hào)的內(nèi)容與變量n的值拼接在一起
System.out.println("n="+n+", m="+m);
int age=12;
int month=12;
System.out.println("年齡:"+age);
System.out.println("月份:"+month);
}
三元運(yùn)算符
public static void main(String[] args) {
// TODO Auto-generated method stub
三元運(yùn)算符
* 公式: 條件表方式?表達(dá)式1:表達(dá)式2;
* 如果條件表方式的值為true 則返回表達(dá)式1的結(jié)果
* 如果條件表方式的值為false 則返回表達(dá)式2的結(jié)果
int a=1;
int b=2;
System.out.println(5==2?a+b:a-b);
}
流程控制語句
* 語法:
* if(條件表達(dá)式){//if語句塊
* 語句塊內(nèi)容的代碼(不固定)
* }
*
* 如果條件表達(dá)式的結(jié)果為true, 則執(zhí)行語句塊內(nèi)的代碼
* 如果條件表達(dá)式的結(jié)果為false,則不執(zhí)行語句塊內(nèi)的代碼
* if(條件表達(dá)式){
*
* }else{
*
* }
* 如果if中的條件表達(dá)式結(jié)果為true, 則執(zhí)行if語句塊的代碼
* 如果if中的條件表達(dá)式結(jié)果為false,則執(zhí)行else語句塊的代碼
int m=1;
if(m>=2){
System.out.println("1>=2");
}else{
System.out.println("1<2");
}
* if-else if
* 語法結(jié)構(gòu)不固定息堂,可以寫多個(gè)else if條件
* 其中每一個(gè)if語句塊都是獨(dú)立嚷狞,只會(huì)執(zhí)行其中一個(gè)
* 如果存在多個(gè)條件成立的if語句塊
* 則執(zhí)行第一個(gè)成立的if語句塊
int m=5;
if(m>8){
System.out.println("a");
}else if(m>4){
System.out.println("b");
}else if(m>1){
System.out.println("c");
}
* switch(num){括號(hào)中的內(nèi)容是整型數(shù)值
* case 1:
* 執(zhí)行的代碼;
*
* case 2:
* ...
* break; 保證每個(gè)case語句獨(dú)立執(zhí)行
*
* default:如果所有case都不符合條件荣堰,則執(zhí)行default
int num=5;
switch(num){
case 2:
System.out.println("b");
break;
case 3:
System.out.println("c");
break;
case 1:
System.out.println("a");
break;
case 4:
System.out.println("d");
break;
default:
System.out.println(num);
}
switch中可以使用的數(shù)據(jù)類型
switch()中可以使用那些數(shù)據(jù)類型
int ,byte ,short,char可以
long 不可以
JDK1.7開始 switch中可以使用字符串作為參數(shù)(指的的switch括號(hào)中的內(nèi)容)
* while(條件表達(dá)式){
* 執(zhí)行的代碼
* }
*
* 首先判斷條件表達(dá)式結(jié)果床未,如果為true
* 則執(zhí)行while語句塊中的代碼,代碼執(zhí)行之后
* 再一次判斷條件表達(dá)式的結(jié)果是否為true
* 如果為true 振坚,則繼續(xù)執(zhí)行代碼
* 直到條件為false的時(shí)候薇搁,結(jié)束循環(huán)
int m=10;
while(m>1){
if(m%2==0){
System.out.println("m="+m);
}
m--;
}
do-while:先執(zhí)行一次代碼,再進(jìn)行判斷
int n=1;
do{
System.out.println("n="+n);
n++;
}while(n<=10);
* for(循環(huán)變量的初始化;循環(huán)條件;循環(huán)變量的改變){
* 執(zhí)行的代碼
* }
* 執(zhí)行順序:
* 1.循環(huán)變量的初始化
* 2.循環(huán)條件
* 3.執(zhí)行的代碼
* 4.循環(huán)變量的改變
* 5.循環(huán)條件
* 如果條件為true,重復(fù)以上操作
* 如果條件為false,結(jié)束for循環(huán)
for(int i=1;i<=10;i++){
System.out.println(i);
}
循環(huán)嵌套:應(yīng)用單層for循環(huán)的執(zhí)行過程渡八,依次執(zhí)行
for(int i=1;i<=5;i++){
for(int j=1;j<=5;j++){
System.out.println("i="+i+" j="+j);
}
}
* 中斷循環(huán)
* break:如果在循環(huán)結(jié)構(gòu)中執(zhí)行了break啃洋,
* 則整個(gè)循環(huán)停止传货,繼續(xù)執(zhí)行循環(huán)外的代碼
*
* continue:如果在循環(huán)結(jié)構(gòu)中執(zhí)行了continue,
* 會(huì)跳過當(dāng)前循環(huán)宏娄,執(zhí)行下一次循環(huán)
for(int i=1;i<=10;i++){
if(i==5){
break;
}
System.out.println("當(dāng)前i="+i);
}
System.out.println("華麗的分割線--------------");
for(int j=1;j<=10;j++){
if(j==5){
continue;如果執(zhí)行力continue,則它之后代碼不會(huì)執(zhí)行
直接進(jìn)行下一次循環(huán)
}
System.out.println("當(dāng)前j="+j);
}
變量作用域問題
變量只在聲明時(shí)它所在的塊內(nèi)有效
int n=2;
if(n>1){
int m=5;
System.out.println(m);
}
System.out.println(m); 會(huì)出現(xiàn)編譯報(bào)錯(cuò)问裕,無法使用變量m
數(shù)組
數(shù)組:用于存儲(chǔ)一組相同數(shù)據(jù)類型的容器
* 數(shù)組中的數(shù)據(jù)叫做元素,每一個(gè)元素都有一個(gè)對(duì)應(yīng)的下標(biāo)
* 第一個(gè)元素孵坚,下標(biāo)為0僻澎,依次遞增
* 數(shù)組中元素的個(gè)數(shù),表示數(shù)組的長度
創(chuàng)建數(shù)組的方式
創(chuàng)建數(shù)組 聲明一個(gè)int類型的數(shù)組arr 長度是5
int[] arr=new int[5];
聲明一個(gè)int類型的數(shù)組arr1 十饥,數(shù)組中的元素分別是1,2祖乳,3
int[] arr1=new int[]{1,2,3};
int [] arr2={1,2,3};
要求如果聲明了具體的長度就不能聲明具體的元素
如果聲明了具體的元素就不能聲明具體的長度
int[] arr2=new int[5]{1,2,3,4,5}; 編譯報(bào)錯(cuò)
會(huì)出現(xiàn)編譯報(bào)錯(cuò)逗堵,數(shù)組只能存放相同數(shù)據(jù)類型的元素
int[] arr3=new int[]{2.1,5,3};
不同數(shù)據(jù)類型數(shù)組的默認(rèn)值
int[],byte[],short[],long[]中元素默認(rèn)值是0
char[] 元素默認(rèn)值是空字符
double[],float[]元素默認(rèn)值0.0
boolean []元素默認(rèn)值false
操作數(shù)組中的元素
int[] arr=new int[]{4,5,7,3,1};
int num=arr[2];獲取元素值
System.out.println(num);
arr[0]=9;對(duì)元素賦值
System.out.println(arr[0]);
數(shù)組的長度屬性 length, arr.length
System.out.println(arr.length);
arr.length=20; 只讀屬性,不能重新賦值眷昆,會(huì)編譯報(bào)錯(cuò)
遍歷數(shù)組:將數(shù)組的每一個(gè)元素獲取出來
int[] arr=new int[]{5,4,6,1,2};
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
在編碼時(shí)蜒秤,如果使用了數(shù)組中不存在的下標(biāo),并不會(huì)出現(xiàn)編譯報(bào)錯(cuò)
但是在程序執(zhí)行時(shí)亚斋,會(huì)出現(xiàn)數(shù)組下標(biāo)越界的異常
System.out.println(arr[5]);
java.lang.ArrayIndexOutOfBoundsException
二維數(shù)組:數(shù)組中每一個(gè)元素還是一個(gè)數(shù)組
int[][] arr1=new int[2][3];
int[][] arr=new int[][]{{4,5},{9,2,3}};
System.out.println(arr.length);外層數(shù)組的長度
System.out.println(arr[0].length);內(nèi)層小數(shù)組長度
System.out.println(arr[1].length);內(nèi)層小數(shù)組長度
該聲明方式不會(huì)編譯報(bào)錯(cuò)作媚,但運(yùn)行程序則出現(xiàn)空指針異常
int[][] arr2=new int[2][];
java.lang.NullPointerException 空指針異常
由于內(nèi)層數(shù)組并不存在,arr2[0],arr2[1] 的值為null
使用null掉用數(shù)組的屬性帅刊,會(huì)報(bào)出空指針異常
操作二維數(shù)組元素
int[][] arr=new int[][]{{4,5},{9,2,3}};
System.out.println(arr[0][0]);
System.out.println(arr[1][2]);
...
遍歷二維數(shù)組
for(int i=0;i<arr2.length;i++){
for(int j=0;j<arr2[i].length;j++){
System.out.println(arr2[i][j]);
}
}
冒泡排序
每一輪相鄰的兩個(gè)數(shù)之間進(jìn)行兩兩比較纸泡,如果前一個(gè)數(shù)比后一個(gè)數(shù)大
則交換位置,一輪之后則找出最大值赖瞒。之后其余的數(shù)據(jù)進(jìn)行新一輪的
兩兩比較找出最大值女揭,直到?jīng)]有相鄰的兩個(gè)數(shù)再需要比較。
* 冒泡排序: 9,3,8,2,7,1
* 第一輪 :3栏饮,8吧兔,2,7,1,9 5次
* 第二輪: 3,2袍嬉,7,1,8 4次
* 第三輪: 2境蔼,3,1,7 3次
* 第四輪: 2伺通,1箍土,3 2次
* 第五輪: 1,2 1次
for(int i=1;i<arr.length;i++){表示需要比較多少輪
for(int j=0;j<arr.length-i;j++){表示每輪需要比較多少次
if(arr[j]>arr[j+1]){如果前一個(gè)元素大于后一個(gè) 互換位置
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
快速排序
int []arr=new int[]{9,3,8,2,7,1};
快速排序方法 只能按照升序排列
Arrays.sort(arr);
1和5表示下標(biāo)范圍罐监,可以修改涮帘。
Arrays.sort(arr,1,5);
數(shù)組的復(fù)制
int[] arrOld=new int[]{5,9,4,5,4,8};
int[] arrNew=new int[6];//0 0 9 4 5 0
* 數(shù)組的復(fù)制
* 第一個(gè)參數(shù):源數(shù)組(被復(fù)制的數(shù)組)
* 第二個(gè)參數(shù):從源數(shù)組的第幾個(gè)下標(biāo)開始復(fù)制元素
* 第三個(gè)參數(shù):目標(biāo)數(shù)組(接收復(fù)制元素的新數(shù)組)
* 第四個(gè)參數(shù):從目標(biāo)數(shù)組的第幾個(gè)下標(biāo)開始放置元素
* 第五個(gè)參數(shù):從源數(shù)組中復(fù)制幾個(gè)元素
System.arraycopy(arrOld, 1, arrNew, 2, 3);
int[] arrOld=new int[]{5,9,4,5,4,8};
* 該方法會(huì)創(chuàng)建一個(gè)新數(shù)組
* 第一個(gè)參數(shù):源數(shù)組
* 第二個(gè)參數(shù):新數(shù)組的長度
int[] arrNew=Arrays.copyOf(arrOld,6);
內(nèi)存空間
方法的定義
* 方法:用于解決一段具有特定功能的代碼
*
* 方法的定義:
* [修飾詞] 返回值類型 方法名([參數(shù)類型 參數(shù)名]){ 方法體 }
*
* 修飾詞 :public ,static等關(guān)鍵字組成 表示該方法的使用(訪問)的權(quán)限
*
* 返回值類型:
* 如果方法中的代碼經(jīng)過計(jì)算后會(huì)得到一個(gè)結(jié)果
* 那么該結(jié)果的數(shù)據(jù)類型 就是方法的返回值類型
* 需要使用關(guān)鍵字 return 返回該結(jié)果
*
* 如何方法中的代碼,沒有結(jié)果值(輸出語句不算結(jié)果值)
* 則方法的返回值類型是 void 關(guān)鍵字
*
* 方法是先聲明笑诅,再實(shí)現(xiàn)內(nèi)容功能代碼
* 所以调缨,方法內(nèi)部有沒有結(jié)果值疮鲫,應(yīng)該取決于是否定義返回值類型
*
* 方法名:就是方法的被執(zhí)行(被調(diào)用)的標(biāo)識(shí)
*
* 參數(shù):參數(shù)表示方法中需要的某些不確定的數(shù)據(jù)
* 數(shù)據(jù)類型 ,變量名
* 參數(shù)的個(gè)數(shù)不固定,可以沒有弦叶,也可以存在多個(gè)
* 根據(jù)方法的具體需求來定
*
* 方法體:表示該方法核心功能的代碼
方法和方法之間是同級(jí)關(guān)系俊犯,不能在方法中定義方法
如果方法想要被執(zhí)行,則需要在main方法中調(diào)用該方法
程序中方法之間可以相互調(diào)用,但不建議調(diào)用main方法
無返回值無參數(shù)類型
public static void sayHi(){
System.out.println(1);
}
調(diào)用無返回值無參數(shù)類型方法
public static void main(String[] args) {
sayHi();
}
定義具有返回值類型的方法
如果定義的方法具有明確的返回值類型
則方法的內(nèi)部必須返回一個(gè)對(duì)應(yīng)的結(jié)果
public static int test1(){
return 2;
}
public static double test2(){
return 1.0;
}
public static boolean test3(){
return false;
}
調(diào)用方式
public static void main(String[] args) {
調(diào)用有返回值的方法
存在返回值的方法伤哺,可以當(dāng)做一個(gè)值使用
System.out.println(test1()); - -2
short a=(short)test1();
System.out.println(a); - -2
}
如果在方法中出現(xiàn)return ,表示方法的結(jié)束燕侠,不再向下執(zhí)行代碼。
定義具有參數(shù)的方法
參數(shù)根據(jù)方法的功能來設(shè)定
求數(shù)值5 加上一個(gè)未知數(shù)的和
public static void test4(int a){
System.out.println(5+a);
}
public static void test5(int a,int b){
System.out.println(a+b);
}
public static int test6(int n){
如果在方法中出現(xiàn)return
表示方法的結(jié)束立莉,不再向下執(zhí)行代碼
return n+5;
}
調(diào)用方式
調(diào)用有參數(shù)的方法绢彤,需要傳入與參數(shù)類型對(duì)應(yīng)的數(shù)據(jù)
public static void main(String[] args) {
test4(5);
test5(10,2);
System.out.println(test6(55));
}
方法調(diào)用的過程:實(shí)際就是將實(shí)參傳遞給形參的過程
public static void main(String[] args) {
// TODO Auto-generated method stub
sum(1,2);實(shí)參
int a=1;
int b=2;
sum(a,b);實(shí)參
}
public static int sum(int a,int b){形參
return a+b;
}
方法定義練習(xí)
求1—100之間的整數(shù)和
public static int test1(){
int sum=0;
for(int i=1;i<=100;i++){
sum+=i;
}
return sum;
}
求1—100之間能被3整除的數(shù)有多少個(gè)
public static int test2(){
int count=0;
for(int i=1;i<=100;i++){
if(i%3==0){
count++;
}
}
return count;
}
求兩個(gè)整數(shù)區(qū)間內(nèi)的所有整數(shù)和
public static int test3(int a,int b){
int sum=0;
if(a==b){
sum=a;
}else if(a<b){
for(int i=a;i<=b;i++){
sum+=i;
}
}else{
for(int i=b;i<=a;i++){
sum+=i;
}
}
return sum;
}
隨機(jī)輸入不相同的三個(gè)整數(shù) 比較出其中的最大值
public static int test4(int a,int b,int c){
int max=0;
if(a>b&&b>c){
max=a;
}else if(a>c&&c>b){
max=a;
}else if(b>a&&a>c){
max=b;
}else if(b>c&&c>a){
max=b;
}else{
max=c;
}
return max;
}
求兩個(gè)整數(shù)之間存在多少個(gè)奇數(shù)
public static int test5(int a,int b){
int count=0;
if(a>b){
for(int i=b;i<=a;i++){
if(i%2!=0){
count++;
}
}
}else{
for(int i=a;i<=b;i++){
if(i%2!=0){
count++;
}
}
}
return count;
}
隨機(jī)輸入一個(gè)年份 判斷是否為閏年
public static void test6(int year){
if(year%4==0&&year%100!=0||year%400==0){
System.out.println("閏年");
}else{
System.out.println("不是閏年");
}
}
有5位學(xué)員參加了Java知識(shí)競(jìng)賽的決賽,輸出決賽的平均成績(jī)
public static double test7(int[] scores){
double avg=0;//平均值
double sum=0;//總和
for(int i=0;i<scores.length;i++){
sum+=scores[i];
}
avg=sum/scores.length;
return avg;
}
求一個(gè)整數(shù)的階乘
public static int test8(int n){
int num=1;
for(int i=n;i>0;i--){
num*=i;
}
return num;
}
計(jì)算數(shù)列 升序后的排列結(jié)果
public static void test9(int[] arr){
Arrays.sort(arr);
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
方法的重載
在同一個(gè)類中蜓耻,允許存在多個(gè)相同名字的方法
重載的規(guī)則:
方法名相同
參數(shù)不同:個(gè)數(shù)不同或者類型不同
返回值類型可以相同茫舶,也可以不同
面向?qū)ο?/h5>
類:Java中一種特殊的數(shù)據(jù)類型 - -引用數(shù)據(jù)類型
類:是一組具有相同特征和行為的事物的抽象
對(duì)象:類的一個(gè)具體的實(shí)例
類可以衍生出不同的對(duì)象,每個(gè)對(duì)象都有著類中共同的特征和行為
類的定義
public class Person {
特征在類中叫做屬性 (與之前學(xué)的變量相同)
String name;//名字
int age;//年齡
double height;//身高
double weight;//體重
構(gòu)造器(構(gòu)造方法)
* 編寫一個(gè)類刹淌,一定要含有一個(gè)構(gòu)造器
* 如果編寫的類中饶氏,沒有任何形式的構(gòu)造器
* Java編譯器則會(huì)提供一個(gè)默認(rèn)構(gòu)造器
*
* 如果類中已經(jīng)存在了一種形式的構(gòu)造器
* 則編譯器不再提供默認(rèn)構(gòu)造器
public Person(){無參構(gòu)造器/默認(rèn)默認(rèn)構(gòu)造器
}
構(gòu)造器的重載
提供有參構(gòu)造器 在創(chuàng)建對(duì)象時(shí),可以直接對(duì)屬性賦值
對(duì)屬性進(jìn)行初始化操作
public Person(int age1){有參構(gòu)造器
age=age1;
}
行為在類中叫做方法
public void eat(){
System.out.println("吃飯...");
}
public void sleep(){
System.out.println("睡覺...");
}
}
調(diào)用類中的屬性和方法
創(chuàng)建類的對(duì)象 類名 對(duì)象名(與變量名同理) = new 構(gòu)造器;
Person p1=new Person();
通過對(duì)象.屬性 和 對(duì)象.方法 進(jìn)行調(diào)用.
類中的屬性具有默認(rèn)值
System.out.println(p1.name);
p1.eat();
不同的對(duì)象之間不會(huì)相互影響
Person p1=new Person();
System.out.println("p1:"+p1.age);
System.out.println("p1:"+p1.name);
Person p2=new Person();
System.out.println("p2:"+p2.age);
System.out.println("p2:"+p2.name);
創(chuàng)建對(duì)象時(shí)有勾,構(gòu)造器的形式必須是在類中已經(jīng)存在
否則無法使用疹启,會(huì)出現(xiàn)編譯報(bào)錯(cuò)
this:表示當(dāng)前類的對(duì)象
* 使用有參構(gòu)造器對(duì)屬性賦值
* 如果參數(shù)名與屬性名相同時(shí)
* 提供this進(jìn)行區(qū)分
*
* this:表示當(dāng)前類的對(duì)象
public Student(int age){
this();表示當(dāng)前類的無參構(gòu)造器
this.age=age;
System.out.println("有參構(gòu)造器");
}
內(nèi)存空間
棧:存取速度比堆快,效率高蔼卡。
棧內(nèi)保存基本數(shù)據(jù)類型的局部變量和對(duì)象的引用
堆:保存對(duì)空間要求大的內(nèi)容喊崖,如對(duì)象的屬性,數(shù)組的元素
內(nèi)層圖.png
Java中的變量類型
局部變量:聲明在方法中的變量或者方法中的參數(shù)
實(shí)例變量:類中的屬性雇逞,又叫全局變量贷祈。
靜態(tài)變量:類中static修飾的屬性,又叫類變量
匿名對(duì)象 :如果對(duì)一個(gè)對(duì)象只需要進(jìn)行一次方法的調(diào)用
new Person();
垃圾回收機(jī)制
Java中的垃圾回收機(jī)制是自動(dòng)的喝峦,垃圾回收機(jī)制實(shí)際上是JVM內(nèi)部一個(gè)優(yōu)先級(jí)比較低的后臺(tái)線程势誊,垃圾回收機(jī)制僅作用于堆,與棧無關(guān)
產(chǎn)生垃圾的情況
- 對(duì)象的引用被賦值為null
- 一次性使用匿名對(duì)象
- 超出生命周期的對(duì)象
變量的作用域
類變量:在類被加載時(shí)創(chuàng)建谣蠢,只要類存在粟耻,靜態(tài)變量就存在。
實(shí)例變量:在類的整個(gè)生命周期都有效
局部變量:只在方法的調(diào)用過程中有效眉踱,方法調(diào)用結(jié)束后失效
面向?qū)ο? - 繼承 (子類 extends 父類)
Java中一個(gè)類可以繼承另一個(gè)類,被繼承的類 稱為父類挤忙,另外一個(gè)稱為子類
子類繼承父類之后,可以使用父類的屬性和方法
但是父類不能使用子類的屬性和方法
繼承的優(yōu)點(diǎn)
有利于程序的擴(kuò)展谈喳, 增強(qiáng)了代碼的復(fù)用
繼承的特性
單一性繼承 册烈,一個(gè)子類只能有一個(gè)父類,但一個(gè)父類可以有多個(gè)子類
子類實(shí)例化過程
- 子類實(shí)例化時(shí),先實(shí)例化其父類婿禽,再實(shí)例化子類
- 子類實(shí)例化會(huì)先實(shí)例化其父類赏僧,父類構(gòu)造器調(diào)用完畢大猛,才執(zhí)行子類構(gòu)造器
- 子類繼承父類,在子類的構(gòu)造方法的第一句一定會(huì)調(diào)用父類的構(gòu)造方法
- 如果父類沒有明確的構(gòu)造方法淀零,父類使用的是默認(rèn)構(gòu)造器挽绩。
- 在子類構(gòu)造方法中會(huì)默認(rèn)調(diào)用父類的默認(rèn)構(gòu)造器, super()可以不寫
- 子類在自己的構(gòu)造器中使用super關(guān)鍵字調(diào)用父類的構(gòu)造器 super(參數(shù)1)
- 如果子類調(diào)用了父類的無參構(gòu)造器 而父類中沒有無參構(gòu)造器則會(huì)編譯報(bào)錯(cuò)
super關(guān)鍵字
作用:調(diào)用父類構(gòu)造器 super( );
super( )括號(hào)中參數(shù)列表的形式驾中,決定調(diào)用父類那個(gè)形式的構(gòu)造器
只能出現(xiàn)在子類構(gòu)造器中唉堪,且必須在第一行
面向?qū)ο?- - 封裝
封裝: 對(duì)類中的屬性和方法規(guī)定訪問權(quán)限,保護(hù)類中數(shù)據(jù)的安全
將類中的信息(屬性和方法)隱藏起來肩民,不允許外部程序直接訪問唠亚,
而是通過該類 提供的方法進(jìn)行訪問
訪問權(quán)限:用來控制類的成員和類的使用范圍
- private:私有地
- default:默認(rèn)地
- protected:受保護(hù)的
- public:公共的
訪問權(quán)限可以修飾屬性和方法 ,其中public 和 默認(rèn) 可以修飾類
面向?qū)ο?- - 多態(tài)
多態(tài)的體現(xiàn):子類和父類之間持痰,不同的子類之間對(duì)于同一行為灶搜,有不同的實(shí)現(xiàn)方式
方法的重寫
對(duì)從父類中繼承的方法進(jìn)行重新改造
方法重寫的規(guī)則
- 方法名相同
- 參數(shù)列表相同(數(shù)量,類型共啃,順序相同)
- 返回值類型相同
- 子類方法的訪問權(quán)限不小于父類方法的訪問權(quán)限
重寫方法被調(diào)用時(shí),看對(duì)象類型暂题。子類對(duì)象的重寫方法被調(diào)用時(shí)移剪,引用類型無論是父類還是子類,運(yùn)行的都是子類重寫后的版本薪者。
重寫和重載的區(qū)別
重寫:遵循“運(yùn)行期”的綁定纵苛,根據(jù)對(duì)象類型進(jìn)行調(diào)用
重載:遵循“編譯器”的綁定,根據(jù)參數(shù)列表不同進(jìn)行調(diào)用
多態(tài)的體現(xiàn):引用數(shù)據(jù)類型的轉(zhuǎn)換
上溯造型(向上造型):父類的引用指向子類的對(duì)象
優(yōu)點(diǎn):有利于程序的維護(hù)和擴(kuò)展言津。
static關(guān)鍵字
static可以修飾屬性攻人,方法和代碼塊,但是不能修飾局部變量
靜態(tài)變量- static修飾的變量
該變量也稱為類變量悬槽,被該類的所有對(duì)象共享怀吻,在類被加載時(shí)創(chuàng)建
只要類存在,靜態(tài)變量就存在
訪問方式:類名.屬性名 或者 對(duì)象.屬性名
靜態(tài)方法 - -static修飾的方法
不需要實(shí)例化對(duì)象初婆,可以直接訪問
訪問方式:類名.方法名 或 對(duì)象.方法名
靜態(tài)方法的注意事項(xiàng)
- 靜態(tài)方法中只能直接訪問靜態(tài)屬性
- 靜態(tài)方法中不能使用this,super
- 靜態(tài)方法不能被重寫蓬坡,不能修飾構(gòu)造器
靜態(tài)塊 - - static修飾的代碼塊
當(dāng)前類被加載時(shí),靜態(tài)代碼塊被執(zhí)行磅叛,且只被執(zhí)行一次
通常用來對(duì)屬性進(jìn)行初始化屑咳,加載靜態(tài)資源
單例模式:保證一個(gè)僅有一個(gè)實(shí)例
單例編寫模式
- 私有構(gòu)造器
- 該類對(duì)象作為私有靜態(tài)屬性
- 公共的靜態(tài)方法
final關(guān)鍵字
final修飾的類不能被繼承
final修飾的方法不能被重寫
final修飾的變量不能被重新賦值
如果聲明屬性時(shí)使用fianl修飾,屬性不再有默認(rèn)值
常量 :所有對(duì)象共享弊琴,不需要經(jīng)常修改的數(shù)據(jù) - static final
Java的異常處理機(jī)制
Java程序在編譯或運(yùn)行期間兆龙,發(fā)生的不可預(yù)期的意外,造成程序不能繼續(xù)執(zhí)行的情況
Java中的異常是被管理起來的,當(dāng)程序發(fā)生異常敲董,會(huì)創(chuàng)建出一個(gè)異常的對(duì)象
Throwable 所有異常的父類
Error 錯(cuò)誤:天災(zāi) 人力不可抗拒 計(jì)算機(jī)硬件的問題紫皇,比如:硬盤壞了慰安,內(nèi)存掉電
Exception 異常: 人禍 主要是因?yàn)槌绦蜷_發(fā)者不嚴(yán)謹(jǐn)造成的問題,可以通過代碼來修補(bǔ)和解決
檢查性異常
非檢查異常
異常捕獲機(jī)制
try{
可能發(fā)生異常的代碼
}catch(Exception e){
發(fā)生異常則執(zhí)行此處代碼
}finally{
無論如何都會(huì)執(zhí)行
}
throws 表示某個(gè)方法向上拋出異常
throw 人工制造異常
Object類:Java中所有類的父類
創(chuàng)建一個(gè)自定義類, 類的對(duì)象會(huì)調(diào)用出一些
類中不存在的方法坝橡,這些方法的都是繼承于Object類
Object類中的方法
equals(Object obj) -boolean
比較兩個(gè)對(duì)象是否為同一個(gè)對(duì)象(實(shí)際比較對(duì)象的地址是否相同)
Person p=new Person(12,"jack");
Person p1=new Person(12,"jack");
System.out.println(p.equals(p1)); - -false
== 和equals 的區(qū)別
== :比較基本數(shù)據(jù)類型的變量時(shí)泻帮,比較的是變量的值是否相同
比較引用數(shù)據(jù)類型時(shí),比較的兩個(gè)對(duì)象的地址是否相同
equals():Obejct類中的方法计寇,默認(rèn)比較的是兩個(gè)對(duì)象的地址是否相同
一般Object的子類會(huì)重寫該方法锣杂,從而比較的的是內(nèi)容是否相同
在Person類中重寫equals( )
重寫equals() 從而比較兩個(gè)對(duì)象之間的內(nèi)容是否相同
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
測(cè)試類
Person p=new Person(12,"jack");
Person p1=new Person(12,"jack");
System.out.println(p.equals(p1)); - -true
hashCode() 返回對(duì)象的哈希值(int)
如果兩個(gè)對(duì)象的equals()比較為true,則兩個(gè)對(duì)象的hashCode值相同
如果兩個(gè)對(duì)象的equals()比較為false 那么兩個(gè)對(duì)象的hashCode值可能相同,也可能不同
toString( ) 返回對(duì)象的字符串表現(xiàn)形式
直接使用輸出語句打印一個(gè)對(duì)象 會(huì)得到該對(duì)象地址的字符串表現(xiàn)顯示
子類重寫Object中的方法番宁,直接輸出的對(duì)象 會(huì)得到對(duì)象的屬性信息
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
包裝類
//包裝類和基本數(shù)據(jù)類型之間可以直接轉(zhuǎn)換
Integer m=20;
Integer k=n;
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
//Integer.parseInt(String s) -int
//將字符串轉(zhuǎn)為int 方法中的字符串必須是純數(shù)字形式的
//否則會(huì)出現(xiàn)轉(zhuǎn)換異常 java.lang.NumberFormatException
String number="12";
System.out.println(number+1);//121
int a=Integer.parseInt(number);
System.out.println(a+1);//13
//Integer.valueOf(String s) - Integer
String num1="12";
Integer numi=Integer.valueOf(num1);
System.out.println(numi);
//Integer.toString(int i) -String
String str=Integer.toString(5);
System.out.println(str+1);
Math類
//Math類中的屬性和方法
System.out.println(Math.PI);
//絕對(duì)值方法 Math.abs(int i) -int
System.out.println(Math.abs(-20));
//求立方根方法 Math.cbrt(double d) - double
System.out.println(Math.cbrt(8));
//向上取整 元莫,返回大于或等于參數(shù)的最小整數(shù) Math.ceil(double d) -double
System.out.println(Math.ceil(-0.0));
//向下取整 ,返回小于或等于參數(shù)的最大整數(shù) Math.floor(double d) -double
System.out.println(Math.floor(0.9));
//返回兩個(gè)數(shù)的最大值 Math.max(int a, int b) -int
System.out.println(Math.max(5, 8));
//返回兩個(gè)數(shù)的最小值 Math.min(int a, int b) -int
System.out.println(Math.min(10, 8));
//返回[0.0,1.0)之間的隨機(jī)小數(shù) Math.random() - double
System.out.println(Math.random());
//四舍五入 Math.round(double d) - long
System.out.println(Math.round(5.0));
//求平方根方法 Math.sqrt(double d) -double
System.out.println(Math.sqrt(25));
System.out.println(Math.random()*10+5);
Random ran=new Random();
int d=ran.nextInt(1000);//[0,1000)
System.out.println(d);
Date類
- 創(chuàng)建Date對(duì)象
Date date =new Date( ); 格林威治時(shí)間的當(dāng)前系統(tǒng)時(shí)間
getTime( ) - long 獲取當(dāng)前時(shí)間距1970年的毫秒值
setTime( ) - Date
SimpleDateFormat 日期格式轉(zhuǎn)換
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss:SS");
Date date=new Date();
System.out.println(date);//Mon Aug 20 16:42:32 CST 2018
--format(Date d) -String 將日期類型的數(shù)據(jù)轉(zhuǎn)換成字符串形式
String time1= sdf.format(date);
System.out.println(time1);
日歷類
Calendar cal=Calendar.getInstance();
System.out.println(Calendar.YEAR);
System.out.println(cal.get(Calendar.YEAR));
System.out.println(cal.get(Calendar.MONTH)+1);//月份比實(shí)際值少1
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.HOUR));
System.out.println(cal.get(Calendar.MINUTE));
System.out.println(cal.get(Calendar.SECOND));
String類
字符串的定義
String str="abc";
String str1="";//空字符串
System.out.println(str1);
String str2=new String();//空字符串
System.out.println(str2);
String str3=new String("hello");
System.out.println(str3);
字符串的方法
字符串也存在下標(biāo) 蝶押,第一個(gè)字符下標(biāo)為0
String str="Tinking in Java";
charAt(int index) -char 根據(jù)參數(shù)下標(biāo)返回對(duì)應(yīng)的字符
System.out.println(str.charAt(7));
length() -int 獲取字符串長度
System.out.println(str.length());
concat(String s) -String 將參數(shù)字符串連接到原字符串的末尾
得到一個(gè)新的字符串 對(duì)原字符串的內(nèi)容沒有影響
System.out.println(str.concat(" hello"));
* Tinking in Java
* 子串:in,ava
endsWith(String s) -boolean 判斷當(dāng)前字符串是否以參數(shù)(子串)為后綴
System.out.println(str.endsWith("Java"));
//equals(Object obj) - boolean 判斷字符串與參數(shù)內(nèi)容是否相同
System.out.println(str.equals("abc"));
indexOf(String s) -int 返回參數(shù)字符串在原字符串中第一次出現(xiàn)的位置
位置以參數(shù)字符串中第一個(gè)字符為準(zhǔn)
如果不存在參數(shù)字符串 則返回 -1
System.out.println(str.indexOf("in"));
System.out.println(str.indexOf("abc"));
indexOf(String s, int i) - int
從指定下標(biāo)開始查找踱蠢,參數(shù)字符串在原字符串中第一次出現(xiàn)的位置
System.out.println(str.indexOf("in", 2));
lastIndexOf(String s) -int 返回參數(shù)字符串在原字符串中最后一次出現(xiàn)的位置
System.out.println(str.lastIndexOf("in"));
isEmpty() -boolean 判斷當(dāng)前字符串是否為空字符串(長度為0) 是 -true , 不是 -false
System.out.println(str.isEmpty());
replace(String old, String new) - String
將原字符串中old部分 替換 new 得到一個(gè)新字符串
System.out.println(str.replace("in", "***"));
contains(String s) -boolean 判斷參數(shù)是否為原字符串的子串
System.out.println(str.contains("Jaa"));
startsWith(String str) - boolean 判斷原字符串是否以參數(shù)字符串為前綴
System.out.println(str.startsWith("in"));
substring(int index) -String 從給定下標(biāo)的位置開始截取原字符串 得到一個(gè)新的子串
System.out.println(str.substring(1));
substring(int begin, int end) -String 從給定下標(biāo)的范圍截取原字符串 得到一個(gè)新的子串
System.out.println(str.substring(1, 5));
toCharArray() - char[] 將字符串轉(zhuǎn)換為字符數(shù)組
String類的內(nèi)部是由一個(gè)final修飾的char[]維護(hù)的
char[] ch=str.toCharArray();
toLowerCase() -String 將原字符串中的字母轉(zhuǎn)換為全小寫
System.out.println(str.toLowerCase());
toLowerCase() -String 將原字符串中的字母轉(zhuǎn)換為全大寫
System.out.println(str.toUpperCase());
String str1=" hello world ";
String str2="hello world";
System.out.println(str1.equals(str2));
System.out.println(str1);
trim() -String 將原字符串兩端的空白字符消除掉
System.out.println(str1.trim());
字符串內(nèi)存
如果字符串中包含了字符串對(duì)象 則該內(nèi)容的地址在堆中
StringBuffer和StringBuilder
StringBuffer類沒有重寫Object類中的equals()
所以使用equals()比較兩個(gè)StringBuffer對(duì)象時(shí)
比較的仍然是地址
List集合
List集合(接口):有序,可重復(fù)集合
List list=new ArrayList();//向上造型
System.out.println(list.size()); 集合當(dāng)前的元素個(gè)數(shù)
list.add(12); 集合添加元素
list.add("abc");
list.add("abc");
System.out.println(list.size());
System.out.println(list.get(0)); 提供下標(biāo)獲取元素
System.out.println(list.get(1));
System.out.println(list.get(2));
刪除集合中的與參數(shù)對(duì)象相同的元素
如果參數(shù)是整數(shù)值時(shí)棋电,刪除對(duì)應(yīng)下標(biāo)的元素
list.remove(0);
list.remove("abc");
集合的遍歷
List list=new ArrayList();
list.add("hello");
list.add("tom");
list.add("jack");
通過for循環(huán)遍歷集合
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
for each 遍歷集合
* 冒號(hào)左邊 聲明一個(gè)對(duì)象表示集合中元素(數(shù)據(jù)類型對(duì)應(yīng))
* 冒號(hào)右邊 表示需要遍歷的集合對(duì)象
* 操作obj 就是操作實(shí)際元素
for(Object obj:list){
System.out.println(obj);
}
* 通過迭代器(Iterator接口)遍歷集合
*
* hasNext():判斷游標(biāo)的右邊是否存在下一個(gè)元素
* next():獲取游標(biāo)右邊的元素茎截,并且將游標(biāo)向下移動(dòng)
*
* 使用迭代器遍歷集合的過程中,如果需要?jiǎng)h除元素
* 只能使用迭代器提供的刪除方法
通過集合的iterator() 獲取迭代器
Iterator it=list.iterator();
System.out.println(it.hasNext());
while(it.hasNext()){
System.out.println(it.next());
}
ArrayList 集合底層是由Object[]實(shí)現(xiàn)的, 查詢?cè)氐男矢?/p>
泛型:保證集合中的數(shù)據(jù)是相同的對(duì)象
List<Double> list=new ArrayList<Double>();
List集合中的元素如果是自定義類型(例 :Person)赶盔,無法使用Collections.sort() 對(duì)該集合中的元素進(jìn)行排序企锌,因?yàn)樽远x類本身不存在大小規(guī)則。
解決方法: 自定義類實(shí)現(xiàn)Comparable<T> ,可以對(duì)該類添加比較大小的規(guī)則(該類的對(duì)象之間比較大小)
public class Person implements Comparable<Person>{
/重寫該方法 于未,根據(jù)類的屬性自定義比較大小的規(guī)則
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return this.age-o.age;
}
}
Java定義好的類撕攒,已經(jīng)實(shí)現(xiàn)了Comparable<T>接口
從而確定了自身比較大小的規(guī)則,如果該規(guī)則不適用于
我們的程序當(dāng)中烘浦,可以重新定義一個(gè)比較器Comparator接口
public class ComparImp implements Comparator<String>{
@Override
public int compare(String s1, String s2) {
// TODO Auto-generated method stub
return s1.length()-s2.length();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list=new ArrayList<String>();
ComparImp c=new ComparImp(); 比較器對(duì)象
list.add("哈哈");
list.add("不國人民");
list.add("天真和");
Collections.sort(list,c); 重載方法
for(String s:list){
System.out.println(s);
}
}
Set集合
set集合(接口):不存在重復(fù)元素,元素存取的順序不同
Set<String> set=new HashSet<String>(); 定義方式
set.add("abc"); 添加元素
set.add("哈哈");
set.add("hello");
set.add("abcdef");
set.add("中國");
System.out.println(set.size()); 集合元素個(gè)數(shù)
System.out.println(set.isEmpty()); 判斷集合是否為空
System.out.println(set.contains("中國人"));判斷集合是否包含該元素
set.clear();清空集合
遍歷集合
Iterator<String> it=set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
TreeSet集合:會(huì)將內(nèi)部元素按照元素自身的大小規(guī)則抖坪,升序排序
Map:存儲(chǔ)元素以鍵值對(duì)的形式進(jìn)行存儲(chǔ)(key-value) ,其中key不可以重復(fù)
Map<String,Integer> map=new HashMap<String,Integer>(); 定義方式
map.put("數(shù)學(xué)", 90); 添加元素
map.put("英語", 90);
map.put(null,null); map可以使用null作為key
System.out.println(map.get("英語")); 通過key獲取value
System.out.println(map.remove("數(shù)學(xué)")); 通過key刪除元素 key-value同時(shí)刪除
System.out.println(map.size()); 元素個(gè)數(shù)
System.out.println(map.get("數(shù)學(xué)")); 如果key不存在,返回結(jié)果是null
System.out.println(map.get(null));
System.out.println(map.containsKey("英語")); 判斷map中是否包含key
遍歷Map的三種方式
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("數(shù)學(xué)", 90);
map.put("英語", 93);
map.put("Java",92);
keySet() - Set<T> 將Map中所有的key 獲取出來放入Set集合中
Set<String> keySet= map.keySet();
通過遍歷set集合獲取集合中的每一個(gè)key
for(String key:keySet){
System.out.println(map.get(key));
}
* map底層實(shí)際上維護(hù)了一個(gè)Entry實(shí)例
* Entry提供了兩個(gè)不同的方法闷叉,分別獲取key和value
Set<Entry<String,Integer>> entrySet=map.entrySet();
for(Entry<String,Integer> entry:entrySet){
System.out.println(entry.getKey()+":"+entry.getValue());
}
values() 將map中所有的值獲取出來 放入Collection中
Collection<Integer> values=map.values();
for(Integer value:values){
System.out.println(value);
}
File 文件類
File f1=new File("D:/a.txt"); 定義方式
File f2=new File("D:/hello");
System.out.println(f1.exists()); 判斷文件對(duì)象是否存在
System.out.println(f1.length()); 獲取文件的字節(jié)大小
System.out.println(f1.getName()); 獲取文件名
System.out.println(f2.exists());
System.out.println(f2.getName());
System.out.println(f1.getPath());獲取文件路徑
System.out.println(f2.getPath());
File[] files=f2.listFiles(); 獲取目錄下的子選項(xiàng)(文件和目錄)
System.out.println(files.length);
for(File f:files){
System.out.println(f.getName());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
File f1=new File("D:/b.txt");
try {
boolean flag=f1.createNewFile();
if(flag){
System.out.println("文件創(chuàng)建成功");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
File f1=new File("D:/hello");
if(f1.mkdir()){
System.out.println("目錄創(chuàng)建成功");
}
}
先創(chuàng)建目錄 再創(chuàng)建文件
public static void main(String[] args) {
// TODO Auto-generated method stub
//D:/hello/hello.txt
File f1=new File("D:/hello");
File f2=new File("D:/hello/hello.txt");
if(f1.mkdir()){
try {
f2.createNewFile( );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
File f1=new File("D:/n");
//如果目錄中存在子選項(xiàng)的話擦俐,無法直接刪除該目錄
boolean flag=f1.delete();//刪除文件和目錄
if(flag){
System.out.println("目錄刪除成功");
}else{
System.out.println("目錄刪除失敗");
}
}
遞歸方法解決問題
public static void main(String[] args) {
// TODO Auto-generated method stub
將hello目錄中的所有子文件以及子目錄的文件名打印出來
* listFiles(),isDirectory()
*
* 首先獲取一級(jí)目錄下的所有子項(xiàng)
* 遍歷所有子項(xiàng),如果是目錄的話 繼續(xù)遍歷該子目錄下的所有子項(xiàng)
* 重復(fù)以上操作握侧,直到?jīng)]有目錄為止
File f=new File("D:/hello");
getFile(f);
}
public static void getFile(File file){
File[] files=file.listFiles();
for(File f:files){
if(f.isDirectory()){
System.out.println("目錄:"+f.getName());
getFile(f);
}else{
System.out.println("文件:"+f.getName());
}
}
}
字節(jié)輸入流
public static void main(String[] args) {
// TODO Auto-generated method stub
輸入流 :將數(shù)據(jù)從外部(本地磁盤捌肴,網(wǎng)絡(luò))讀取到程序中的流
FileInputStream 屬于字節(jié)流
FileInputStream(File f) ,FileInputStream(String url)
File f=new File("D:/hello.txt");
try {
FileInputStream fis=new FileInputStream(f);
byte [] buff=new byte[10];
int len; 表每次讀取文件信息的位置
StringBuffer s=new StringBuffer();
while((len=fis.read(buff))!=-1){
new String(buff,0,len) 將字節(jié)數(shù)組中的內(nèi)容轉(zhuǎn)換字符串
s.append(new String(buff,0,len));
}
System.out.println(s);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
字節(jié)輸出流
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
字節(jié)輸出流
File f=new File("D:/a.txt");
構(gòu)造器中加入?yún)?shù) true 表示以追加的形式寫入文件內(nèi)容
如果構(gòu)造器中的文件路徑不存在,則會(huì)將文件創(chuàng)建出來
FileOutputStream fos=new FileOutputStream("D:/b.txt",true);
String message="abc";
byte[] buff=message.getBytes();
fos.write(buff); 寫出方法
fos.close();
System.out.println("文件寫出完畢");
}
文件的復(fù)制
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileInputStream fis=new FileInputStream("D:/內(nèi)存圖.png");
FileOutputStream fos=new FileOutputStream("D:/內(nèi)存圖1.png",true);
byte[] buff=new byte[4];
int len;
while((len=fis.read(buff))!=-1){
fos.write(buff, 0, len);
}
fis.close();
fos.close();
System.out.println("文件復(fù)制完畢...");
}
字符流
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
InputStreamReader(FileInputStream fis)
對(duì)于純文本文件 字符流的讀寫效率更高藕咏,但是字符流只能讀寫純文本文件
long time1=System.currentTimeMillis();當(dāng)前時(shí)間到1970-1-1所經(jīng)歷的毫秒值
FileInputStream fis=new FileInputStream("D:/a.txt");
InputStreamReader isr=new InputStreamReader(fis);字符輸入流
char[] cuff=new char[5];
int len;
StringBuffer s=new StringBuffer();
while((len=isr.read(cuff))!=-1){
s.append(new String(cuff,0,len));
}
isr.close();
long time2=System.currentTimeMillis();
System.out.println(time2-time1);
}
字符串輸入流的內(nèi)容 維護(hù)了一個(gè)字符緩沖區(qū)每一次寫出的數(shù)據(jù)并不能直接寫入到文件中而是存放在緩沖區(qū)中状知,只有關(guān)閉流時(shí),會(huì)將緩沖區(qū)中的數(shù)據(jù) 全部寫出
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream fos=new FileOutputStream("D:/b.txt",true);
OutputStreamWriter osw=new OutputStreamWriter(fos);
String message="大集合";
osw.write(message);
osw.flush(); 該方法會(huì)將緩沖區(qū)的內(nèi)容一次性寫出
osw.close();
System.out.println("寫出完畢...");
}
高級(jí)流 孽查,處理流
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedInputStream 高級(jí)流(處理流) 輸入流
FileInputStream fis=new FileInputStream("D:/b.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
byte[] buff=new byte[4];
int len;
StringBuffer s=new StringBuffer();
while((len=bis.read(buff))!=-1){
s.append(new String(buff,0,len));
}
System.out.println(s);
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream fos=new FileOutputStream("D:/c.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
String message="大家好...";
byte[] buff=message.getBytes();
bos.write(buff);
bos.close(); 方法的內(nèi)部饥悴,調(diào)用了flush()
}
實(shí)現(xiàn)多線程的方式
- 定義一個(gè)類,繼承Thread 重寫run方法
- 定義一個(gè)類,實(shí)現(xiàn)Runnable接口 重寫run方法
線程的方法
Thread.currentThread() 返回當(dāng)前正在執(zhí)行線程對(duì)象
getName() 線程名
da.setName("線程da"); 設(shè)置線程名.
setPriority(Thread.MAX_PRIORITY);//設(shè)置線程優(yōu)先級(jí)方法
start(); 啟動(dòng)線程西设,啟動(dòng)線程之后會(huì)自動(dòng)調(diào)用線程對(duì)應(yīng)的run方法
Thread.sleep(100); 當(dāng)前線程會(huì)睡眠100毫秒之后 瓣铣,再繼續(xù)執(zhí)行
join() ,在線程A中 調(diào)用線程B的join()贷揽,則線程A 會(huì)等待線程B執(zhí)行結(jié)束
線程的生命周期
線程安全問題
多個(gè)線程對(duì)象訪問同一個(gè)資源棠笑,導(dǎo)致數(shù)據(jù)錯(cuò)亂
public class ThreadDemo implements Runnable{
/*
* 多線程存在線程安全問題
* 多個(gè)線程對(duì)象訪問同一個(gè)資源,導(dǎo)致數(shù)據(jù)錯(cuò)亂
*/
static int n=100; //表示100張車票
@Override
public void run() {
while(n>0){
shellNum();
}
}
/*
* synchronized 同步關(guān)鍵字 禽绪,同步方法
* 只有當(dāng)前進(jìn)入方法的線程執(zhí)行完畢后蓖救,其他
* 線程才可以進(jìn)入方法
*/
public synchronized void shellNum(){
if(n>0){
System.out.println(Thread.currentThread()
.getName()+" 賣出了第"+n+"張票");
n--;
}
}
}
網(wǎng)絡(luò)編程
網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸。
為了能夠方便的識(shí)別網(wǎng)絡(luò)上的每個(gè)設(shè)備印屁,網(wǎng)絡(luò)中的每個(gè)設(shè)備都會(huì)有一個(gè)唯一的數(shù)字標(biāo)識(shí)循捺,這個(gè)就是IP地址。在計(jì)算機(jī)網(wǎng)絡(luò)中,現(xiàn)在命名IP地址的規(guī)定是IPv4協(xié)議雄人,該協(xié)議規(guī)定每個(gè)IP地址由4個(gè)0-255之間的數(shù)字組成从橘,例如10.0.120.34。每個(gè)接入網(wǎng)絡(luò)的計(jì)算機(jī)都擁有唯一的IP地址础钠,這個(gè)IP地址可能是固定的恰力,例如網(wǎng)絡(luò)上各種各樣的服務(wù)器,也可以是動(dòng)態(tài)的旗吁,例如使用ADSL撥號(hào)上網(wǎng)的寬帶用戶踩萎,無論以何種方式獲得或是否是固定的,每個(gè)計(jì)算機(jī)在聯(lián)網(wǎng)以后都擁有一個(gè)唯一的合法IP地址阵漏,就像每個(gè)手機(jī)號(hào)碼一樣
IP地址解決了在網(wǎng)絡(luò)中找到一個(gè)計(jì)算機(jī)的問題驻民,但是為了讓一個(gè)計(jì)算機(jī)可以同時(shí)運(yùn)行多個(gè)網(wǎng)絡(luò)程序翻具,就引入了另外一個(gè)概念——端口(port)履怯。
在同一個(gè)計(jì)算機(jī)中每個(gè)程序?qū)?yīng)唯一的端口,這樣一個(gè)計(jì)算機(jī)上就可以通過端口區(qū)分發(fā)送給每個(gè)端口的數(shù)據(jù)了裆泳,換句話說叹洲,也就是一個(gè)計(jì)算機(jī)上可以并發(fā)運(yùn)行多個(gè)網(wǎng)絡(luò)程序,而不會(huì)在互相之間產(chǎn)生干擾工禾。
在網(wǎng)絡(luò)通訊中运提,第一次主動(dòng)發(fā)起通訊的程序被稱作客戶端(Client)程序,簡(jiǎn)稱客戶端,而在第一次通訊中等待連接的程序被稱作服務(wù)器端(Server)程序闻葵,簡(jiǎn)稱服務(wù)器民泵。一旦通訊建立,則客戶端和服務(wù)器端完全一樣槽畔,沒有本質(zhì)的區(qū)別栈妆。
例如QQ程序,每個(gè)QQ用戶安裝的都是QQ客戶端程序,而QQ服務(wù)器端程序則運(yùn)行在騰訊公司的機(jī)房中鳞尔,為大量的QQ用戶提供服務(wù)嬉橙。這種網(wǎng)絡(luò)編程的結(jié)構(gòu)被稱作客戶端/服務(wù)器結(jié)構(gòu),也叫做Client/Server結(jié)構(gòu)寥假,簡(jiǎn)稱C/S結(jié)構(gòu)市框。
網(wǎng)絡(luò)通信方式
TCP(傳輸控制協(xié)議)方式
-
UDP(用戶數(shù)據(jù)報(bào)協(xié)議)方式
在Java語言中,對(duì)于TCP方式的網(wǎng)絡(luò)編程提供了良好的支持糕韧,在實(shí)際實(shí)現(xiàn)時(shí)枫振,java.Net.Socket類代表客戶端連接,以java.net.ServerSocket類代表服務(wù)器端連接兔沃。在進(jìn)行網(wǎng)絡(luò)編程時(shí)蒋得,底層網(wǎng)絡(luò)通訊的細(xì)節(jié)已經(jīng)實(shí)現(xiàn)了比較高的封裝,所以在程序員實(shí)際編程時(shí)乒疏,只需要指定IP地址和端口號(hào)碼就可以建立連接了额衙。
客戶端
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
int port=8088;//表示服務(wù)端的端口號(hào)
String ip="localhost";//表示本機(jī)IP
String message="服務(wù)端 hello";//項(xiàng)服務(wù)器發(fā)送的消息
//創(chuàng)建客戶端
Socket socket=new Socket(ip,port);
System.out.println("客戶端已啟動(dòng)...");
//獲取網(wǎng)絡(luò)輸出流 向服務(wù)端發(fā)送消息
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
osw.write(message);
osw.flush();
//關(guān)閉socket
socket.close();
}
服務(wù)端
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//創(chuàng)建服務(wù)端 設(shè)置端口號(hào)
ServerSocket ss =new ServerSocket(8088);
System.out.println("服務(wù)端已啟動(dòng)...");
//accept(); 是一個(gè)阻塞方法 ,該方法在監(jiān)聽是否
//有客戶端連接到該服務(wù)端怕吴,沒有客戶端連接窍侧,該方法會(huì)一直阻塞
//該方法可以獲取socket對(duì)象 用于獲取客戶端的內(nèi)容
Socket socket=ss.accept();
System.out.println("客戶端已連接...");
//獲取網(wǎng)絡(luò)輸入流 讀取客戶端信息
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String message="";
while((len=isr.read(chff))!=-1){
message=new String(chff,0,len);
}
System.out.println("客戶端:"+message);
//關(guān)閉socket
socket.close();
}
持續(xù)交互
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
int port =8088;
String ip="localhost";
System.out.println("客戶端已連接...");
while(true){
Socket socket=new Socket(ip,port);
System.out.println("請(qǐng)發(fā)送消息:");
String message=scan.next();//客戶端發(fā)送給服務(wù)端
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw =new OutputStreamWriter(os);
osw.write(message);
osw.flush();
socket.shutdownOutput();//本次輸出流結(jié)束
if("exit".equals(message)){
socket.close();
break;
}
//接收服務(wù)端響應(yīng)的信息
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String mes="";
while((len=isr.read(chff))!=-1){
mes=mes+new String(chff,0,len);
}
System.out.println("服務(wù)端回復(fù):"+mes);
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
//創(chuàng)建服務(wù)端 設(shè)置端口
ServerSocket ss=new ServerSocket(8088);
System.out.println("服務(wù)端已啟動(dòng)...");
while(true){
//socket可以獲取網(wǎng)絡(luò)輸入流 - 得到客戶端的消息
Socket socket=ss.accept();
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String message="";
while((len=isr.read(chff))!=-1){
message=message+new String(chff,0,len);
}
if("exit".equals(message)){
socket.close();
break;
}
System.out.println("客戶端:"+message);
//對(duì)客戶端做出響應(yīng)
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
System.out.println("回復(fù)客戶端:");
String mse=scan.next();//回復(fù)給客戶端的內(nèi)容
osw.write(mse);
osw.flush();
socket.shutdownOutput();
}
}
一個(gè)服務(wù)端對(duì)應(yīng)多個(gè)客戶端
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
//創(chuàng)建服務(wù)端 設(shè)置端口
ServerSocket ss=new ServerSocket(8088);
System.out.println("服務(wù)端已啟動(dòng)...");
while(true){
//socket可以獲取網(wǎng)絡(luò)輸入流 - 得到客戶端的消息
Socket socket=ss.accept();
ServerThread st=new ServerThread(socket);
Thread t=new Thread(st);
t.start();
}
}
public class ServerThread implements Runnable{
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
start();
}
public void start(){
Scanner scan=new Scanner(System.in);
InputStream is;
try {
is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String message="";
while((len=isr.read(chff))!=-1){
message=message+new String(chff,0,len);
}
if("exit".equals(message)){
socket.close();
return;
}
//getInetAddress() 獲取客戶端IP
System.out.println("客戶端"+socket.getInetAddress()+":"+message);
//對(duì)客戶端做出響應(yīng)
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
System.out.println("回復(fù)客戶端:");
String mse=scan.next();//回復(fù)給客戶端的內(nèi)容
osw.write(mse);
osw.flush();
socket.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ClientA {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
int port =8088;
String ip="localhost";
System.out.println("客戶端A已連接...");
while(true){
Socket socket=new Socket(ip,port);
System.out.println("請(qǐng)發(fā)送消息:");
String message=scan.next();//客戶端發(fā)送給服務(wù)端
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw =new OutputStreamWriter(os);
osw.write(message);
osw.flush();
socket.shutdownOutput();//本次輸出流結(jié)束
if("exit".equals(message)){
socket.close();
break;
}
//接收服務(wù)端響應(yīng)的信息
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String mes="";
while((len=isr.read(chff))!=-1){
mes=mes+new String(chff,0,len);
}
System.out.println("服務(wù)端回復(fù):"+mes);
}
}
}
public class ClientB {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
int port =8088;
String ip="localhost";
System.out.println("客戶端B已連接...");
while(true){
Socket socket=new Socket(ip,port);
System.out.println("請(qǐng)發(fā)送消息:");
String message=scan.next();//客戶端發(fā)送給服務(wù)端
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw =new OutputStreamWriter(os);
osw.write(message);
osw.flush();
socket.shutdownOutput();//本次輸出流結(jié)束
if("exit".equals(message)){
socket.close();
break;
}
//接收服務(wù)端響應(yīng)的信息
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
char[] chff=new char[20];
int len;
String mes="";
while((len=isr.read(chff))!=-1){
mes=mes+new String(chff,0,len);
}
System.out.println("服務(wù)端回復(fù):"+mes);
}
}
}
內(nèi)部類
無論外部類是否繼承其他類,不會(huì)影響內(nèi)部類的繼承關(guān)系
從而解決了Java中單一繼承的缺點(diǎn)
public class Outer1{
private String name="Outer1";
private int out1=10;
static int out=11;
public void say(){
System.out.println("Outer");
調(diào)用內(nèi)部的屬性和方法 需要?jiǎng)?chuàng)建內(nèi)部類對(duì)象
Inner inner=new Inner();
inner.getInner();//調(diào)用的內(nèi)部類方法
}
內(nèi)部類 無法聲明static屬性/方法
可以聲明 static final修飾的屬性
可以訪問外部類的屬性和方法(包含 private ,static)
class Inner extends{內(nèi)部類
private int i=5;
static final int inn1=6;
String inName="inner";
public void getInner(){
System.out.println("inner");
System.out.println(name);
System.out.println(out);
}
}
}
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
外部類名.內(nèi)部類名 內(nèi)部類對(duì)象 = 外部類對(duì)象.new 內(nèi)部類構(gòu)造器;
Outer1 out1=new Outer1();
Outer1.Inner inner=out1.new Inner();
System.out.println();
}
}