統計字元串中每一個不同的字元 JDK9的新特性: List介面,Set介面,Map介面裡邊增加了一個靜態方法of,可以給集合一次性添加多個元素 使用前提:當集合中存儲的元素的個數已經確定了,不再改變使用,也就是說,添加完元素之後,就不能再使用put方法來添加元素了 註意事項: 1. of方法只適用於 ...
統計字元串中每一個不同的字元
import java.util.*;
//統計字元串每一個字元出現的字數
public class StringDemo{
public static void main(String[] args){
Scanner aScanner = new Scanner(System.in);
//讓用戶輸入字元串
System.out.println("請輸入你要統計的語句");
String aString = aScanner.next();
//要統計每一個字元,就要把字元串轉換為字元,可以調用字元串的方法toCharArray
char[] aCharArray = aString.toCharArray();
//創建HashMap集合,讓其存儲鍵與值
HashMap<Character,Integer> aHashMap = new HashMap<>();
//遍歷字元數組
for(Character key:aCharArray){
//把aChar作為鍵,先判斷集合中有沒有該鍵,若有則value加一,沒有的話添加鍵進去
if(aHashMap.containsKey(key)){
Integer value =aHashMap.get(key);
value++;
//後來的值會取代前面的值,put方法把值添加進去,
aHashMap.put(key,value);
}else{
//不存在添加進去
aHashMap.put(key,1);
}
}
//把key存儲都Set集合中,遍歷集合
Set<Character> aSet = aHashMap.keySet();
//遍歷aHashMap
for(Character key : aSet){
Integer value = aHashMap.get(key);
System.out.println(key+"="+value);
}
}
}
JDK9的新特性:
List介面,Set介面,Map介面裡邊增加了一個靜態方法of,可以給集合一次性添加多個元素
使用前提:當集合中存儲的元素的個數已經確定了,不再改變使用,也就是說,添加完元素之後,就不能再使用put方法來添加元素了
註意事項:
of方法只適用於List介面,Set介面,Map介面,不適用於介面的實現類
of方法的返回值是一個不能夠改變的集合
Set介面和Map介面在調用of方法適合,不能存放重覆元素,否則會拋出異常
import java.util.*;
public class JDK9Demo{
public static void main(String[] args){
List<String> list = List.of("a","b","c","d","a");//可以重覆元素
System.out.println(list);
Set<String> set = Set.of("a","b","c");//不允許重覆元素
System.out.println(set);
Map<String,Integer> map = Map.of("張三",18,"李四",17,"王五",16,"趙三",18);//不允許重覆元素,鍵不允許重覆,值可以
System.out.println(map);
}
}
Debug追蹤
Debug調試程式
可以讓代碼逐行執行,查看代碼執行的過程,調試程式中出現的bug
f8:逐行執行程式 f7:進入到方法中 shift+f8跳出方法
f9:跳到下一個斷點 ctrl +f2 退出debug模式,停止程式
console:切換到控制台
鬥地主案列
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class DouDiZhu {
public static void main(String[] args){
//Integer表示的索引,String表示牌的大小
HashMap<Integer,String> poker = new HashMap<>();
//創建一個List集合,存儲牌的索引,sort方法可以對索引進行排序
ArrayList<Integer> pokerIndex = new ArrayList<>();
//定義兩個集合,存儲花色和牌的序號
List<String> colors = List.of("♠","♥","♣","♦");
List<String> numbers = List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");
//把大小王存儲到集合中
int index = 0;
poker.put(index,"大王");
pokerIndex.add(0);
index++;
poker.put(index,"小王");
pokerIndex.add(index);
index++;
//0索引代表著大王,1索引代表著小王,以此類推,到後面就可以對索引排序,也就是對牌排序
for(String number : numbers){
for(String color :colors){
String str = color+number;
poker.put(index,str);
//牌的索引也要添加,因為他代表著牌的大小,
pokerIndex.add(index);
index++;
}
}
//使用Collections中的方法shuffle();
Collections.shuffle(pokerIndex);
ArrayList<Integer> p1 = new ArrayList<>();
ArrayList<Integer> p2 = new ArrayList<>();
ArrayList<Integer> p3 = new ArrayList<>();
ArrayList<Integer> p4 = new ArrayList<>();
for(int i=0;i <pokerIndex.size();i++){
//先轉為Integer類型,不然會添加失敗
Integer in = pokerIndex.get(i);
if(i>=51){
p4.add(in);
}else if(i%3==0){
p1.add(in);
}else if(i%3==1){
p2.add(in);
}else if(i%3==2){
p3.add(in);
}
}
//把分完的牌進行排序
Collections.sort(p1);
Collections.sort(p2);
Collections.sort(p3);
Collections.sort(p4);
lookPoker("劉德華",poker,p1);
lookPoker("周潤發",poker,p2);
lookPoker("周星馳",poker,p3);
lookPoker("底牌",poker,p4);
}
public static void lookPoker(String name,HashMap<Integer,String> poker,ArrayList<Integer> list){
System.out.print(name+": ");
for(Integer key : list){
//通過索引獲取值
String value = poker.get(key);
System.out.print(value+" ");
}
System.out.println();
}
}
異常
Throwable有兩個子類Exception和Error
Error:嚴重錯誤error,無法通過處理的錯誤,只能實現避免,好比絕症
Exception:表示異常,異常產生後程式員可以通過代碼的方式糾正,使程式繼續運行,是必須要處理的
throw關鍵字可以在指定的方法裡面拋出指定的異常對象
/*
throw關鍵字
作用:
可以使用throw關鍵字在指定的方法中拋出指定的異常
使用格式:
throw new xxxException("異常產生的原因");
註意:
1.throw關鍵字必須寫在方法的內部
2.throw關鍵字後邊new的對象必須是Exception或者Exception的子類對象
3.throw關鍵字拋出指定的異常對象,我們必須處理這個異常對象
throw關鍵字後邊創建的是RuntimeException或者是RuntimeException的子類對象,我們可以不處理,預設交給jvm處理
throw關鍵字後邊創建的是編譯器異常,我們必須處理這個異常,
*/
public class ThrowDemo{
public static void main(String[] args){
int[] arr= new int[3];
int e = getElement(arr,-2);
System.out.println(e);
//拋出指定了異常
//Exception in thread "main" java.lang.NullPointerException: 傳遞的數組是空
//at ThrowDemo.getElement(ThrowDemo.java:24)
//at ThrowDemo.main(ThrowDemo.java:18)
}
//如果傳遞的參數不合法,那麼我們就必須使用拋出異常的方式,告知方法的調用者,傳遞參數有問題
public static int getElement(int[] arr,int index){
if(index<0 || index>arr.length-1){
throw new ArrayIndexOutOfBoundsException("傳遞的索引不能超過範圍或者低於範圍");
}
if(arr == null){
//如果是空,就指定他為空指針異常
throw new NullPointerException("傳遞的數組是空");
}
int i = arr[index];
return i;
}
}
Objects的非空判斷
Objects.requireNonNull();可以判斷一個對象是否為null
import java.util.Objects;
public class ThrowDemo{
public static void main(String[] args){
method("雲想衣裳花想容");//傳遞null將會返回NullPointerException異常
}
public static void method(Object obj){
Object objects=Objects.requireNonNull(obj);
System.out.println(objects);
}
}
throws關鍵字_異常處理的第一種方式
/*
throws關鍵字:當方法內部拋出異常對象的時候,那麼我們就必須處理這個異常對象,可以使用thorws關鍵字來處理異常對象,會把異常對象聲明拋出給方法的調用者處理
*/
import java.io.FileNotFoundException;
public class ThrowsDemo{
public static void main(String[] args)throws FileNotFoundException{
readFile("d:\\a.txt");
}
public static void readFile(String fileName)throws FileNotFoundException{
//傳遞進來的文件不對就拋出異常
if(!fileName.equals("c:\\a.txt")){
throw new FileNotFoundException("傳遞的文件路徑不對,請重新傳遞");
}
System.out.println("傳遞路徑成功");
}
}
try_catch異常處理的第二種方式
捕獲異常語法格式
try{
編寫可能會出現異常的代碼
}catch(用來接收try中拋出的異常信息 異常類型 e){
處理異常代碼
}
....
catch(){}
註意:
try中可能會拋出多個異常對象,那麼久可以使用多個catch來處理這些異常對象
如果try中產生了異常,那麼就會執行catch中的異常處理邏輯
import java.io.FileNotFoundException;
public class ThrowsDemo1{
public static void main(String[] args){
try{
readFile("d:\\a.txt");
}catch(FileNotFoundException e){
System.out.println("傳遞的文件不對");
}
System.out.println("後續代碼");
}
public static void readFile(String fileName)throws FileNotFoundException{
//傳遞進來的文件不對就拋出異常
if(!fileName.equals("c:\\a.txt")){
throw new FileNotFoundException("傳遞的文件路徑不對,請重新傳遞");
}
System.out.println("路徑沒有問題");
}
}
Throwable類中3個異常處理的方法
getMessage() :簡短的描述
toString() :詳細的消息字元串
printStackTrace():列印的異常信息最全面
字異常符類
public class Fu{
public void show1()throws NullPointerException,ClassCastException{}
public void show2()throws IndexOutOfBoundsException{}
public void show3()throws IndexOutOfBoundsException{}
class Zi extens Fu{
//子類重寫父類方法是,拋出和父類相同異常
public void show1()throws NullPointerException,ClassCastException{}
//子類重寫父類方法時,拋出父類異常的子類
public void show2()throws ArrayIndexIndexOutOfBoundsException{}
//子類重寫父類方法時,不拋出異常
public void show3(){}
//父類沒有拋出異常,子類也不可以拋出異常,如若有異常,需要try catch處理異常
自定義異常
//自定義一個註冊異常
//需要一個空參數的構造方法,一個帶異常信息的構造方法
//繼承Exception //那麼自定義的異常類就是一個編譯器異常,那就需要throws或者try...catch處理
//繼承的是RuntimeException,那麼異常無序處理,交給虛擬機
public class RegisterException extends Exception{
public RegisterException(){}
public RegisterException(String message){
super(message);
}
}
import java.util.*;
//使用自定義異常類
public class ExceptionDemo{
//定義一個集合,存儲姓名
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
list.add("詹姆斯");
list.add("科比");
list.add("喬丹");
list.add("諾維斯基");
list.add("鄧肯");
System.out.println(list);
//讓用戶輸入昵稱
Scanner sc = new Scanner(System.in);
System.out.println("請輸入你的昵稱");
String nicheng = sc.next();
//向裡面添加姓名,如果不存在則添加成功,如果存在則返回註冊異常
for(String name : list){
//使用字元串的方法equals判斷集合是否存在元素,將會返回一個boolean
//為真,就表示昵稱已經存在,需要返回一個註冊異常
if(name.equals(nicheng)){
try{
throw new RegisterException("親,該昵稱已經被註冊過了");
}catch(RegisterException e){
e.printStackTrace();
return;//一旦放生異常,立馬結束方法
}
}
//遍歷完了,如果沒有發生異常,就表示昵稱可以創建
}
list.add(nicheng);
System.out.println("恭喜您,註冊成功");
}
}
多線程
public class ThreadDemo{
public static void main(String[] args){
MyThread mt = new MyThread();
//執行start方法,開啟線程,執行run方法
//如果使用mt.run();的話程式會在堆記憶體中執行,那就不是多行程了,而是單線程
//每一次使用start();都會開闢一條新的線程,在棧空間裡面執行run方法,多行程的好處就是線程之間互相不影響,cup喜歡哪一個線程就執行哪一個線程
mt.start();
for(int i= 0;i<10;i++){
System.out.println("main線程"+i);
}
}
}
public class MyThread extends Thread{
//重寫run方法
public void run(){
for(int i=0;i<10;i++){
System.out.println("run線程"+i);
}
}
}
Thread類的常用方法
獲取線程名稱的方法
1.使用Thread類中的方法getName
String getName() 返回該線程的名稱,那條線程調用我,我就返其的名稱
2.可以先獲取到當前正在執行的線程,然後使用線程中的方法getName()獲取線程的名稱
public class MyThread1 extends Thread{
public void run(){
/*第一種獲取名字的方式
String name=getName();
System.out.println(name);*/
// 第二種獲取名字的方式
//先獲取當前線程(currentThread是一個靜態方法,可以通過類名直接獲取線程)
Thread t = Thread.currentThread();//這個方法將會返回當前的線程
//通過線程獲取名字
String naem =t.getName();
System.out.println(name);
}
}
public class ThreadName{
public static void main(String[] args){
MyThread1 mt = new MyThread1();
mt.start();
}
}
設置線程名稱
一種通過setName方法,一種通過構造方法來設置
public class ThreadName{
public static void main(String[] args){
MyThread1 mt = new MyThread1();
mt.setName("小強");
mt.start();
new MyThread1("旺財").start();
}
}
public class MyThread1 extends Thread{
public MyThread1(){}
public MyThread1(String name){
super(name);
}
public void run(){
/*第一種獲取名字的方式
String name=getName();
System.out.println(name);*/
// 第二種獲取名字的方式
//先獲取當前線程
Thread t = Thread.currentThread();
//通過線程獲取名字
String name =t.getName();
System.out.println(name);
}
}
sleep方法
是一個靜態方法,使用類名就可以直接調用,讓當前線程睡眠指定時間
創建多線程程式的第二種方式_實現Runnable介面
實現步驟:
1.創建一個Runnable介面的實現類
在實現類中重寫Runnable介面的run方法,設置線程任務
創建一個Runnable介面的實現類對象
創建Thread類對象,構造方法中傳遞Runnable介面的實現類對象
調用Thread類的start方法,開啟線程
public class RunnableImp implements Runnable{ public void run(){ for(int i=0;i<10;i++){ //獲取當前的線程,然後獲取線程名字 System.out.println(Thread.currentThread().getName()+"--"+i); } } }
public class RunnableDemo { public static void main(String[] args){ //創建Runnable介面實現類對象 RunnableImp run = new RunnableImp(); //Thread中有個構造方法可以接Runnable介面作為參數傳遞 new Thread(run).start(); for(int i=0;i<10;i++){ //想要獲取main方法的線程,只能夠用下麵的方式獲取,然後獲取線程名字 System.out.println(Thread.currentThread().getName()+"--"+i); } } }