《Java程序设计》课堂实践内容总结
实践一
要求
修改教材P98 Score2.java, 让执行结果数组填充是自己的学号;
提交在IDEA或命令行中运行结查截图,加上学号水印,没学号的不给成绩
代码
import java.util.Arrays;
public class Score2 {
public static void main(String[] args) {
int[] scores=new int[10];
for(int score:scores){
System.out.printf("%2d",score);
}
System.out.println();
Arrays.fill(scores,20155337);
for(int score:scores){
System.out.printf("%3d ",score);
}
}
}
运行结果截图
实践心得
第一次课堂实践题目十分简单,所以在做的时候没有遇到什么问题,老师给出的问题也十分简单,除了写的时候注意输出格式外,没有什么难点重点。
实践二
要求
在IDEA中以TDD的方式对String类和Arrays类进行学习
测试相关方法的正常,错误和边界情况
- String类
- charAt
- split
- Arrays类
- sort
- binarySearch
提交运行结果截图和码云代码链接,截图没有水印的需要单独找老师验收才有成绩
代码
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class Test20155337 {
@Test
public void testString() {
String s ="abc";
assertEquals('b',s.charAt(1));
}
}
实践问题
需要注意以下两点我做实验时遇到的问题:
•测试sort时输入的是字符串数组还是字符数组这里出现了问题,之后查API发现其实有很多类型。
•测试binarySearch是输入的是double类型的,因为上来就用了字符串数组,导致出错。
运行结果
实践心得
关于测试
1.正常情况我是通过随机选取三个测试用例进行测试的
2.错误情况是直接输入错误答案看是否通过测试
3.边界情况是测试数组第一个和最后一个,截图为正常情况的测试。
关于过程
1.charAT:
•此方法返回位于字符串的指定索引处的字符。该字符串的索引从零开始。
•该方法的返回指定索引处char值。
•所以为了实现单元测试,我在complex.java文件中添加如下代码:
代码:
//测试一
public static char String_charAt(String str, int i) {
return str.charAt(i);
}
//取测试一结果
public static char getString_charAt(String str, int i) {
return String_charAt(str, i);
}
在complex.test中添加如下代码对其进行测试:
@Test
public void testString_charAt() throws Exception {
assertEquals('d', Complex.getString_charAt(str,0));
assertEquals('g', Complex.getString_charAt(str,3));
assertEquals('n', Complex.getString_charAt(str,6));
}
测试数组为:
String str = "asdasfasfsff";
实践三
要求
模拟实现Linux下Sort -t : -k 2的功能。
参考 Sort的实现。提交码云链接和代码运行截图。
import java.util.*;
2
3 public class MySort1 {
4 public static void main(String [] args) {
5 String [] toSort = {"aaa:10:1:1",
6 "ccc:30:3:4",
7 "bbb:50:4:5",
8 "ddd:20:5:3",
9 "eee:40:2:20"};
10
11 System.out.println("Before sort:");
12 for (String str: toSort)
13 System.out.println(str);
14
15 Arrays.sort(toSort);
16
17 System.out.println("After sort:");
18 for( String str : toSort)
19 System.out.println(str);
20 }
21 }
代码
import java.util.*;
public class Mysort20155337 {
public static void main(String[] args) {
String[] toSort = {"aaa:10:1:1",
"ccc:30:3:4",
"bbb:50:4:5",
"ddd:20:5:3",
"eee:40:2:20"};
/*****************以下为添加内容********************/
String[] tmp=new String[toSort.length];
for(int i=0;i<toSort.length;i++)
{
String list[]=toSort[i].split(":");
tmp[i]=list[3];
}
/**************************************************/
System.out.println("Before sort:");
for (String str : toSort)
System.out.println(str);
Arrays.sort(tmp);
/*****************以下为添加内容********************/
String []t=new String[toSort.length];
for(int i=0;i<toSort.length;i++)
for(int j=0;j<toSort.length;j++)
if(toSort[j].charAt(9)==(tmp[i].toCharArray()[0]))
t[i]=toSort[j];
/**************************************************/
System.out.println("After sort:");
for (String str : t)
System.out.println(str);
}
}
实践问题
1.regex是什么,而又应该填什么;使用split方法时又应该用什么样的格式来使用这一方法……
带着这些疑问,我上到网上去查相关资料,发现split的用法是建立在一个String类的数组中其中的regex意思是以什么分隔符为标准,并对字符串进行分隔,用的时候分隔符要放在双括号中如:
若以"aa:10:1:1"中的":"为分隔符
"aa:10:1:1"--->"aa" "10" "1" "1"
这样一来就知道split的方法之一了,还有一个在regex参数后添加一个整形数。
2.解决了split的知识点后,仍然有新的麻烦——字符串是属于分开的状态,怎样才可以将怎段完整的字符串进行排序?
在经过一段时间的思考和纸上的运算后,可以利用老师给的模板用两个循环来实现这个想法。
•首先创建一个新的字符串数组来存放新排列的字符串。
•创建两个互相镶嵌的循环来实现字符串的新排列
•第一个循环来将新排列的字符串放进新数组中
•第二个循环用来匹配,是否满足我要求的列排序
完成后代码如下:
import java.util.*;
public class MySort {
public static void main(String [] args) {
String [] toSort = {"aaa:10:1:1",
"ccc:30:3:4",
"bbb:50:4:5",
"ddd:20:5:3",
"eee:40:2:20"};
System.out.println("Before sort:");
for (String str: toSort)
System.out.println(str);
int [] k2 = new int[toSort.length];
for(int i =0;i<toSort.length;i++){
String[] div = toSort[i].split(":");
k2[i]=Integer.parseInt(div[1]);
}
Arrays.sort(k2);
String[] save = new String[k2.length];
for(int i=0;i<toSort.length;i++)
for (int k = 0; k < k2.length; k++) {
if (toSort[i].substring(4,6).equals(String.valueOf(k2[k]))) {
save[k]=toSort[i];
}
}
System.out.println();
System.out.println("After sort:");
for(int i =0;i<save.length;i++){
System.out.println(save[i]);
}
}
}
运行结果截图
实践心得
1>Arrays.sort()使用的是“经过调优的快速排序法
2>比如int[],double[],char[]等基数据类型的数组,Arrays类之只是提供了默认的升序排列,没有提供相应的降序排列方法
2.对对象数组的排序
要实现对对象数组的排序,要先实现Comparable或者Comparator接口。下面先简单了解以下这两个接口以及它们的差别:
1> Comparable 是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。
实践四
要求
在IDEA中或命令行中运行P242 StackTraceDemo2.java
代码运行结果和教材一致吗?为什么?
代码
/**
* Created by crazymosquito on 2017/3/28.
*/
public class StackTraceDemo2 {
public static void main(String[] args) {
try {
c();
}catch (NullPointerException ex) {
ex.printStackTrace();
}
}
static void c() {
try {
b();
}catch (NullPointerException ex) {
ex.printStackTrace();
throw ex;
}
}
static void b() {
a();
}
static String a() {
String text=null;
return text.toUpperCase();
}
}
有区别,因为包不同。
我运行的结果是:at StackTraceDemo2.a(StackTraceDemo2.java:25)
教材上是:at cc.openhome.StackTraceDemo2.a(StackTraceDemo2.java:28)
教材代码上定义了包package cc.openhome;而我的代码则缺省了package的定义。
实践问题
StackTraceDemo2.java: 重抛异常,StackTrace仍然从产生处追踪
•fillStackTrack()方法:让异常堆栈起点为重抛异常的地方,会重新装填异常堆栈,将起点设为重抛异常的地方,返回Throwable对象
运行结果截图
实践五
要求
编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能
提交测试代码和运行结果截图,加上学号水印,提交码云代码链接。
深入学习Linux下od命令
命令格式:
- od [] []
-t命令详解:
-t<TYPE>,--format=TYPE:指定输出格式,格式包括a、c、d、f、o、u和x,各含义如下:
a:具名字符;
c:ASCII字符或者反斜杠;
d[SIZE]:十进制,正负数都包含,SIZE字节组成一个十进制整数;
f[SIZE]:浮点,SIZE字节组成一个浮点数;
o[SIZE]:八进制,SIZE字节组成一个八进制数;
u[SIZE]:无符号十进制,只包含正数,SIZE字节组成一个无符号十进制整数;
x[SIZE]:十六进制,SIZE字节为单位以十六进制输出,即输出时一列包含SIZE字节。
实践问题
- 1:用new FileInputStream("...")指定文件名时,最初我写的字符串是"~/zjy20155312/exam20170531/abc",编译没有问题,但运行时显示找不到文件。
解决办法:向老师求助,老师用pwd命令找到了所在文件夹的全路径名"/home/zjy/zjy20155312/exam20170531",将文件名替换为"/home/zjy/zjy20155312/exam20170531/abc",解决了这个问题。
- 2:0d命令显示的第一列七个数字是什么含义,怎么编程实现?
解决办法:通过查资料,左侧第一列为默认的地址,格式为七位八进制。通过找规律,我发现其数值是该行第一个字符的序号值(从0到length-1)对应的的八进制数,最开始我准备编写一个十进制转八进制的函数来显示这七位数字,后来突然想到可以用八进制输出格式来简化这个问题,即"%07o"不足7位的地方补零。
注:地址值隔一行显示一次,所以将其放在了每行显示16个字符并输出一个换行符之后。
代码
IO源代码(教材P305-306)
import java.io.*;
public class IO {
public static void dump(InputStream src, OutputStream dest)
throws IOException {
try (InputStream input = src; OutputStream output = dest) {
byte[] data = new byte[1024];
int length;
while ((length = input.read(data)) != -1) {
output.write(data, 0, length);
}
}
}
}
我的代码
IO.java:
/**
* Created by hp430 on 2017/5/31.
*/
import java.io.*;
public class IO {
public static void dump(InputStream src, OutputStream dest)
throws IOException {
try (InputStream input = src; OutputStream output = dest) {
byte[] data = new byte[1024];
int k=input.read(data,0,data.length);
System.out.println(new String(data));
for(int i=0;i<data.length;i++) {
if(data[i]!=0) {
System.out.printf("%c ",data[i]);
if(i%16==0&&i!=0) {
System.out.println();
}
}
}
System.out.println();
int[] in=new int[data.length];
for(int i=0;i<in.length;i++) {
in[i]=data[i]&0xff;
}
for(int i=0;i<data.length;i++) {
if(in[i]!=0) {
System.out.print(Integer.toString(in[i],0x10)+" ");
if(i%16==0&&i!=0) {
System.out.println();
}
}
}
System.out.println();
/*int length;
while ((length = input.read(data)) != -1) {
output.write(data, 0, length);
}*/
}
}
}
MyOD20155337.java:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by hp430 on 2017/5/31.
*/
public class MyOD20155337 {![](http://images2015.cnblogs.com/blog/1074385/201706/1074385-20170611224643481-1473295124.png)
public static void main(String[] args) throws IOException {
IO.dump(new FileInputStream(args[0]),System.out);
}
}
代码运行截图
实践心得
这次的代码主要需要解决以下四方面的问题
1将文件导入与关闭
2输出七位行号(最右边那个数为0)
3按每行16个的方式输出其本身
4按每行16个的方式输出对应的ASCII码
还有一些细节问题容易出错
计数变量需要放对位置(这个导致我曾一直只输出同一行字符,查了一下录入的字符串是将信息读取完毕的了,所以发现是计数变量放错了)
做行数方法时,当要输出7位数,而其实行号不满七位需要前面补零。同时,在这个小程序中最后一位是0,综合以上原因,我选择用整型数组填充。用中间数组存放转换过的一个整型行数,在把中间数组赋给最终数组。在这些转换的过程中,用于计数和指示位置的变量尤其容易出错,报错一般也是由于什么数组越界。
输出行号时只输出偶数行号,可以通过判定奇偶是否输出,也可以通过改变调用输出方法的位置,我最后选择了第二种。
十进制数转十六进制可以这样
char a = 'a';
int c = a;
System.out.printf(Integer.toHexString(c));
实践六
实践要求
在IDEA中对P145 MathTool.java 使用JUnit进行单元测试,测试用例不少于三个,要包含正常情况,边界情况。
提交测试代码和运行结果截图,加上学号水印,提交码云代码链接。
实践内容
1、书上P145代码如下:
public class mathTool {
public static int sum(int...numbers) {
int sum=0;
for(int number:numbers){
sum+=number;
}
return sum;
}
}
2、测试代码:
import junit.framework.TestCase;
import org.junit.Test;
/**
* Created by lenovo on 2017/5/17.
*/
public class MathToolTest extends TestCase {
@Test
public void testSum() throws Exception {
assertEquals(1,MathTool.sum(1));
assertEquals(5,MathTool.sum(2,3));
assertEquals(0,MathTool.sum(0));
assertEquals(-2,MathTool.sum(-1,-1));
}
}
代码运行结果截图
实践心得
单元测试是整个测试流程中最基础的部分,它们要求程序员尽可能早地发现问题,并给予控制,这是其一。另外,如果集成测试出现问题,它们可以帮助诊断。这样就为在软件开发流程中建立高效的事件反应机制打下了坚实基础。JUnit就是为Java
程序开发者实现单元测试提供一种框架,使得Java单元测试更规范有效,并且更有利于测试的集成。
实践七
实践要求
提交测试结果截图,课下把代码上传到码云。
求命令行传入整数参数的和。
实践代码
public class CLSum {
public static void main(String [] args) {
int sum = 0;
// 参考Integer类中的方法把字符串转为整数
// 补充代码求命令行参数的args中整数数据的和
for(String arg: args)
sum += Interger.parseInt(arg);
// 打印
System.out.println(sum);
}
}
实践问题
问题:递归实验中,出现以下问题:
int无法转换为int[]
解决方法:
将代码int sum=clSum(10)改为
分析原因:递归函数clSum中的参数是int [] 类型,而调用语句int sum = clSum(10),中的“10”为int类型,两者无法兼容,产生冲突。并且,要传进来的参数是数组的值,而并非个数,因此传10本身就是错误的。
修改为int[] x=new int[10];int sum=clSum(x)后,x为int [] 类型,与被调参数的类型一致,问题解决。
实验分析
本次实验实际上很简单,最核心的就是通过Integer将字符串转换为数字,然后换一种方式,练习递归函数的调用。应该解决的最主要的问题就是:数组中是以字符串的形式存储的,因此应当首先将字符串转换为数字,才能进行接下来的求和运算。
代码运行结果截图
实验心得
学到了什么
首先,学会了Integer的用法,如何实现将字符串转换为数字;然后巩固了递归调用的思想和具体方法。以后遇到此类问题会较快发现问题,从而不在类似方面犯错。
感悟与体会
通过本次实践的练习,了解到基础知识不牢固。刚开始Integer用法不熟练,然后又出现了类型转换不兼容的问题,在检查错误和查阅资料方面,花费了相当长的时间。
因此要多注重基础知识的积累,注重平时。
实践八
实践要求
实现一个简易计算器Calc,支持+ - x / 和%运算, 从命令行传入计算数据
实验出现的问题
(1)Java计算器在进行混合运算时,不能准备的进行计算,后面输入的数值会覆盖先前输入的数据,造成数据丢失。
主要的解决步骤分为以下几点:
①在文件开头部分定义一个标志性布尔型变量sign,并赋初值为false;
②在加号、减号、乘号、除号的代码里添加if判断语句,如果sign值为false,就另Operator的值为相应的运算符,并改变sign的值为true;
③如果sign的值为true,则执行与等号代码相同的switch„case„选择分支语句;
实践代码
public class Cal {
public static void main(String [] args) {
int result = 0;
if (args.length != 3) {
System.out.println("Usage: java Calc operato1 operand(+ - x / %) operator2");
}
switch (args[1]) {
case "+":
result = Integer.parseInt(args[0]) + Integer.parseInt(args[2]);
break;
case "-":
result = Integer.parseInt(args[0]) - Integer.parseInt(args[2]);
break;
case "x":
result = Integer.parseInt(args[0]) * Integer.parseInt(args[2]);
break;
case "/":
result = Integer.parseInt(args[0]) / Integer.parseInt(args[2]);
break;
case "%":
result = Integer.parseInt(args[0]) % Integer.parseInt(args[2]);
break;
default:
System.out.println("Usage: java Calc operato1 operand(+ - x / %) operator2");
break;
}
System.out.println(args[0] + " " + args[1] + " " + args[2] + " = " + result);
}
}
代码运行结果截图
实验心得
通过对计算器窗体的编写我熟悉 java图形用户界面的设计原理和程序结构熟 悉java awt和swing的组合。学会将书本上的知识运用在实际中,提升 了编程能力。尤其在JavaApplet图形界面的布局方面学到很多,以前布局很乱并且很多布局都是无效的。在此次实践学习中通过查阅很多资料和同学以及老师的帮助,充分发挥了JavaApplet界面布局的优越性。另外按钮功能的实现也是本次课设的一大难点,怎样实现那些功能也是关键因素。