1、 編寫一個類,在main方法中定義一個Map對象(採用泛型),加入若干個對象,然後遍歷並打印出各元素的key和value。
package com.itheima;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Test1 {
public static void main(String[] args) {
//定義一個key值爲String類型,value值爲Integer類型的Map集合,可用於存儲一段話中各個單詞出現次數信息
TreeMap<String,Integer> tm=new TreeMap<String,Integer>();
tm.put("hello", 2);
tm.put("you", 8);
tm.put("are", 4);
tm.put("do", 6);
//第一種方式遍歷TreeMap元素:keySet
Set<String> kSet=tm.keySet();
Iterator<String> it=kSet.iterator();
while(it.hasNext()){
String str=it.next();
Integer val=tm.get(str);
System.out.println(str+" : "+val);
}
System.out.println("============================");
//第二種方式遍歷TreeMap元素:EntrySet
Set<Map.Entry<String, Integer>> eSet=tm.entrySet();
Iterator<Map.Entry<String,Integer>> itor=eSet.iterator();
while(itor.hasNext()){
Map.Entry<String, Integer> me=itor.next();
String s=me.getKey();
Integer v=me.getValue();
System.out.println(s+" : "+v);
}
}
}
2、 有五個學生,每個學生有3門課(語文、數學、英語)的成績,寫一個程序接收從鍵盤輸入學生的信息,輸入格式爲:name,30,30,30(姓名,三門課成績),然後把輸入的學生信息按總分從高到低的順序寫入到一個名稱"stu.txt"文件中。要求:stu.txt文件的格式要比較直觀,打開這個文件,就可以很清楚的看到學生的信息。
package com.itheima;
/*
* 思路:1. 定義Student對象,讓其自身具備比較性,同時複寫toString方法,方便後面寫入文件
* 2. 將鍵盤輸入封裝成字符緩衝流,按行讀取,每一行字符串封裝成一個Student對象
* 3. 將Student對象放到TreeSet集合中,實現按序存儲
* 4. 將TreeSet集合中的各個Student對象寫入到stu.txt文件中
*/
import java.io.*;
import java.util.Iterator;
import java.util.TreeSet;
public class Test2 {
public static void main(String[] args) throws Exception
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new FileWriter("stu.txt"));
TreeSet<Student> ts=new TreeSet<Student>();
String line=null;
System.out.println("請輸入學生信息,格式如name,30,30,30:");
//將從鍵盤接收到學生信息放到一個TreeSet集合中
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
String[] strs=line.split(",");
if(strs.length!=4){
System.out.println("輸入信息格式不對,請重新輸入");
continue;
}
ts.add(fillStu(strs));
}
bufr.close();
//將TreeSet寫入到stu.txt文件中
Iterator<Student> it=ts.iterator();
while(it.hasNext()){
Student stu=it.next();
bufw.write(stu.toString());
bufw.newLine();
}
bufw.flush();
bufw.close();
}
//根據一個字符串數組信息填充生成Student對象
public static Student fillStu(String[] strs){
Student stu=new Student(strs[0],Float.parseFloat(strs[1]),Float.parseFloat(strs[2]),Float.parseFloat(strs[3]));
return stu;
}
}
//定義Student類,實現帶泛型的Comparable接口,讓Student對象自身具備比較性
class Student implements Comparable<Student>{
private String name;
private float yuWen;
private float shuXue;
private float yingYu;
private float sum;
public Student(String name, float yuWen, float shuXue, float yingYu) {
super();
this.name = name;
this.yuWen = yuWen;
this.shuXue = shuXue;
this.yingYu = yingYu;
this.sum=yuWen+shuXue+yingYu;
}
@Override
//複寫compareTo()方法,實現Student對象按總分比較,總分一致時按姓名比較
public int compareTo(Student o) {
float result=this.sum-o.sum;
if(result>0)
return -1;
else if(result==0){
return this.name.compareTo(o.name);
}
return 1;
}
public String toString(){
return name+", 語文成績:"+yuWen+" 數學成績:"+shuXue+" 英語成績:"+yingYu+" ---- 總分:"+sum;
}
}
3、 自定義枚舉 Week 用於表示星期,Mon,Tue,Wed...要求每個枚舉值都有toLocaleString 方法,用於獲得枚舉所表示的星期的中文格式 星期一、星期二、星期三...
package com.itheima;
public class Test3{
public static void main(String[] args){
//測試實現的enum枚舉,枚舉對象的中文格式是否可以正常顯示
Week wed=Week.Wed;
System.out.println(wed.toLocalString());
}
}
enum Week {
//定義Mon,Tue,Wed...等枚舉對象,使用內部類形式實現抽象方法
Mon {
public String toLocalString() {
return "星期一";
}
},
Tue {
public String toLocalString() {
return "星期二";
}
},
Wed {
public String toLocalString() {
return "星期三";
}
},
Thu {
public String toLocalString() {
return "星期四";
}
},
Fri {
@Override
public String toLocalString() {
return "星期五";
}
},
Sat {
public String toLocalString() {
return "星期六";
}
},
Sun {
public String toLocalString() {
return "星期天";
}
};
//定義枚舉類的抽象方法
public abstract String toLocalString();
}
4、 請說明Java中字符'\'的含義,有什麼作用?
package com.itheima;
/*
* 答:1.'\'可以轉義字符,將其後面緊跟的字母或符號轉換成其它的含義。
* 常用的轉義字符有:\n:換行,\b:退格,\r:按下回車鍵,\t:製表符,相當於tab鍵。
* 2. 因爲'\'會轉義後面的字符,所以代碼中如果要保持\原先的意思,需要在 \前面再加一個\,表示後面的\保持原形,不轉義
*/
5、 將字符串中進行反轉。abcde --> edcba
package com.itheima;
/*
* 思路:將待轉換的字符串先轉換成字符數組,對字符數組進行首尾互換,即實現了反轉,再將首尾互換後的字符數組封裝成字符串返回
*/
public class Test5 {
public static void main(String[] args) {
String str="abcdefghi";
System.out.println(rev(str));
}
public static String rev(String str){
//將字符串轉換成字符數組
char[] chs=str.toCharArray();
int len=str.length();
char temp;
//實現字符數組首尾互換
for(int i=0;i<len/2;i++){
temp=chs[i];
chs[i]=chs[len-1-i];
chs[len-1-i]=temp;
}
//字符數組封裝成字符串返回
return new String(chs);
}
}
6、 分析以下程序運行結果,說明原理。(沒有分析結果不得分)。---下面直接分析給出的代碼,原題中只有代碼,沒有任何註釋。
package com.itheima;
//分析如下:
public class Test6 {
public static void main(String args[]) {
MyThread t = new MyThread();
//僅調用t.run()並沒有啓動線程,只是普通的函數調用
t.run();
//t線程啓動,開始在一個與主線程不同的線程分支運行run方法中的代碼,t線程與主線程搶奪CPU資源
//run方法一開始就休眠,所以主線程搶到CPU時間,開始運行下面的System.out.println("A")
t.start();
System.out.println("A");
}
}
class MyThread extends Thread {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
//休眠結束運行下面的語句
System.out.println("B");
}
}
/*
程序運行結果是
B
A
B
運行結果分析:
1. JVM啓動後,從main函數入口,開始執行,並創建main主線程
2. 主線程創建MyThread對象t,但t所代表的線程還沒有啓動
3. 主線程調用線程對象t的run()方法,這時還是沒有啓動t線程,只是普通的函數調用,所以程序會sleep 3秒,然後打印B
4. 主線程調用t.start(),t線程被啓動,開始有一個線程分支在運行,分支中運行的是t.run中的代碼,而main主線程仍在main函數中往下執行
5. t線程分支和main主線程開始搶奪CPU時間,因爲t線程分支中run方法中一開始就sleep 3秒,所以主線程輕而易舉地搶到執行權,繼續往下執行,
6. main函數的下一條語句是打印A,所以輸出A,這時,main主線程執行完畢
7. 主線程完畢後,t線程分支還沒休眠結束,所以console控制檯應該會停頓差不多3秒的時間,然後t線程中接着執行run方法中的剩餘語句,打印B.
*/
7、 有一個類爲ClassA,有一個類爲ClassB,在ClassB中有一個方法b,此方法拋出異常,在ClassA類中有一個方法a,請在這個方法中調用b,然後拋出異常。在客戶端有一個類爲TestC,有一個方法爲c ,請在這個方法中捕捉異常的信息。完成這個例子,請說出java中針對異常的處理機制。
package com.itheima;
/*
* 思路:將一個int型值轉換成ASCII碼字符,如果int值超過了127,拋出異常,用這個例子來切合題目並說明java異常處理機制
*/
public class Test7 {
public static void main(String[] args) {
c();
}
//c()方法中調用A類的a()方法,OutASCIIException異常沒必要再拋給更上層調用者,直接在c()方法中捕獲並處理
public static void c(){
A clsA=new A();
try {
clsA.a();
System.out.println("異常拋出點之後的try塊的語句不執行。。。");
} catch (OutASCIIException e) {
System.out.println(e.toString());
System.out.println("錯誤的數值 是:"+e.getVal());
}
}
}
//A類中的a()方法調用B類的b(int)方法,對異常不做處理,直接在函數聲明中拋出,讓上層調用者處理
class A{
public void a() throws OutASCIIException
{
B clsB=new B();
char d=clsB.b(145);
}
}
//B類,其中的b方法實現int值到ASCII字符的轉換,可能拋出自定義異常OutASCIIException
class B{
public char b(int a) throws OutASCIIException{
if(a>127)
throw new OutASCIIException("超出了ASCII碼值的範圍,轉換成字符失敗:",a);
return (char)a;
}
}
//自定義異常,將一個int型值轉換成ASCII字符,當要轉換的int值超過ASCII碼取值範圍時,拋出異常
class OutASCIIException extends Exception
{
int val;
OutASCIIException(String msg, int val){
super(msg);
this.val=val;
}
int getVal(){
return val;
}
}
/*
* java異常處理機制:
* java通過類的形式來描述異常,將異常封裝成對象。
* java異常體系根節點是Throwable類,它描述了異常的共性(異常信息,引發異常的原因,可拋性等)。
* java提供2種處理異常的方式:
* 1. 用try...catch...finally語句處理
* try中存放可能出現異常的代碼,try塊中異常拋出點之後的語句不會再執行;
* catch捕獲異常並進行異常處理;finall中存放一定會執行的代碼,不管異常有沒有發生。
* 2. 在函數上用throws聲明該函數可能出現的異常類,讓函數的調用者去處理該異常
調用者捕獲該異常後,可以繼續向上throws異常,直到拋給jvm,也可以用try...catch處理。
*/
8、 定義一個文件輸入流,調用read(byte[] b)方法將exercise.txt文件中的所有內容打印出來(byte數組的大小限制爲5)。
package com.itheima;
/*
* 思路:因爲緩衝區數組固定是5個字節大小,而當文件中漢字時,漢字佔2個字節,一次讀取5個字節可能出現截取半個漢字的情況,所以不能急着打印;
* 先分析一次讀取後是否截取到了半個漢字,如果是,只打印前4個字節的內容,然後退回一個字節再讀取,如果不是,直接輸出;
* 由此想到了利用隨機訪問文件流,可以設置當前指針位置,必要時回退一個字節。
*/
import java.io.FileInputStream;
import java.io.RandomAccessFile;
public class Test8 {
public static void main(String[] args) throws Exception
{
RandomAccessFile raf=new RandomAccessFile("exercise.txt","r");
byte[] buf=new byte[5];
int len=0;
int currentPos=0;
while((len=raf.read(buf))!=-1){
String str=new String(buf,0,len);
currentPos=currentPos+len;
int i=0;
//i表示一個ASCII字符字節位置或一個漢字的第一個字節位置,漢字GBK編碼的第一個字節都小於0
while(i<5){
if(buf[i]<0)
i=i+2;
else
i=i+1;
}
//read(buf)後,如果截取到了半個漢字,那buf[4]肯定是一個漢字的第一個字節,buf[4]<0,上面的i=6
if(i==6){
//截取了半個漢字時,應該退回到前一個位置,重新再讀取5個字節
currentPos=currentPos-1;
raf.seek(currentPos);
//只把前4個字節的內容打印出來
System.out.print(str.substring(0,str.length()-1));
}else{
//截取到完整漢字,整個輸出
System.out.print(str);
}
}
}
}
9、 寫一方法,打印等長的二維數組,要求從1開始的自然數由方陣的最外圈向內螺旋方式地順序排列。 如: n = 4 則打印:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
package com.itheima;
/*
* 思路:1. 按螺旋的圈數進行循環,對於n階方陣,螺旋圈數是(n+1)/2.
* 2. 每一圈都是按順時針走,順時針位置上的值依次增加,可以先循環列出向右增長的橫行和向下增長的豎列的值,剩下的半圈的值可利用對稱性得到。
* 3. 裏面一圈的起始值是它外面一圈左側位置上的值加1
*/
public class Test9 {
public static void main(String[] args) {
xzArray(8);
}
public static void xzArray(int n){
int[][] arr=new int[n][n];
//如果每一圈開頭位置相鄰左側位置的值爲start,那每一圈開頭的值就是start+1,最外面一圈的start值設置爲0
int start=0;
//按螺旋的圈數進行循環,給定n值的方陣,其螺旋的圈數(n+1)/2
for(int q=0;q<(n+1)/2;q++){
//除第一圈外,從外向裏,每一圈的開頭起始值是其左側緊鄰位置的值+1,即start+1
if(q!=0){
start=arr[q][q-1];
}
//獲取每一圈往右增長的一行和往下增長的一列的值,每一圈的元素個數是隨着圈從外向內的層次數而變化的,用j表示,i代表每一圈向右的一行相對起始值的偏移
for(int j=q,i=0;j<n-q&&i<=j;j++,i++){
arr[q][j]=start+i+1;
//圈子越向內時,每行或每列的元素個數會減少,所以轉折的越快
arr[j][n-1-q]=start+i+n-2*q;
}
//獲得每一圈往右增長的一行和往下增長的一列的值,向左增長的行數據和向上增長的列數據分別利用對稱特性行到,每對對稱位置的兩個元素加起來的值都是該層最右下角元素值的2倍。
for(int i=q+1;i<n-q;i++){
arr[i][q]=2*arr[n-1-q][n-1-q]-arr[q][i];
arr[n-1-q][i]=2*arr[n-1-q][n-1-q]-arr[i][n-1-q];
}
}
printArray(arr);
}
//打印數組的函數
public static void printArray(int[][] arr){
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
//printf實現格式化打印
System.out.printf("%4d",arr[i][j]);
}
System.out.println();
}
}
}
10、 金額轉換,阿拉伯數字轉換成中國傳統形式。
例如:101000001010 轉換爲 壹仟零壹拾億零壹仟零壹拾圓整
package com.itheima;
/*
* 思路:1. 先試圖將普通的4位數及4位數以下的金額轉換成傳統漢字形式
* 2. 任一長串金額,可以以4位爲一組進行分組,分組內金額的轉換形式與普通單獨的4位數金額一致,分組外,每個分組整合有不同的單位
* 3. 程序可以轉換整數部分長達16位的金額,最高單位是萬億,再向上的單位暫時沒有理清,後面有機會會補充
* 4. 考慮帶小數點的金額,轉換方法類似,相對整數部分攤簡單一些,小數可以精確到小數點後3位數,3位以後的小數沒有可用的單位,不考慮
* 5. 阿拉伯數字與漢字大寫之間的轉換利用查表法實現
*
*/
public class Test10 {
public static void main(String[] args) {
String str="400100001010.098";
//String str="0100";
//System.out.println(four2Ch(str));
num2Ch(str);
}
public static void num2Ch(String str){
String[] strs=str.split("\\.");
int len=strs[0].length();
StringBuilder strBuilder=new StringBuilder();
StringBuilder strB=new StringBuilder();
String[] bigTable={"圓","萬","億","萬億"};
int n=0;
//以4位爲一組,先不帶單位轉換該組爲漢字形式,然後每組再加上對應的"圓","萬","億","萬億"單位
while(len>0){
int start=(len-4)>0?len-4:0;
strB=four2Ch(strs[0].substring(start, len));
strBuilder.insert(0,strB);
if(strB.length()==0){
//有多個連續的零時只顯示一個
if(!strBuilder.toString().startsWith("零")){
strBuilder.insert(strB.length(),"零");
}
}else{
strBuilder.insert(strB.length(),bigTable[n]);
}
n++;
len=len-4;
}
if(strs.length>1){
strBuilder.append(point2Ch(strs[1]));
}else{
strBuilder.append("整");
}
System.out.println(strBuilder.toString());
}
//將一個任意4位以內的數轉換成中國傳統貨幣形式
public static StringBuilder four2Ch(String str){
StringBuilder strB=new StringBuilder();
String[] numTable={"零","壹","貳","叄","肆","伍","陸","柒","捌","玖"};
String[] unitTable={"","拾","百","仟"};
int len=str.length();
char[] chArr=str.toCharArray();
for(int i=len-1;i>=0;i--){
//某一位上爲0是,不顯示該位的單位
if(chArr[i]=='0'){
//結尾處的0不轉換,直接去掉,除結尾外,其餘位置有連續的多個零時,只保留一個零
if(i!=len-1&&chArr[i+1]!='0')
strB.append("零");
}
//該位上值不爲0時,轉換該值爲漢字形式,並顯示其單位
else{
strB.append(unitTable[len-1-i]);
strB.append(numTable[chArr[i]-48]);
}
}
return strB.reverse();
}
//將小數轉換成角、分、釐形式
public static StringBuilder point2Ch(String str){
StringBuilder strP=new StringBuilder();
String[] pnumTable={"零","壹","貳","叄","肆","伍","陸","柒","捌","玖"};
String[] punitTable={"角","分","釐"};
int len=str.length();
char[] chArr=str.toCharArray();
for(int i=0;i<len;i++){
if(chArr[i]=='0'){
if(i!=len-1&&chArr[i+1]!='0')
strP.append("零");
}else{
strP.append(pnumTable[chArr[i]-48]);
strP.append(punitTable[i]);
}
}
return strP;
}
}