Java 第二周总结

第二周的作业。

一个简陋的目录

1.本章学习总结

2.Java Q&A

3.使用码云管理Java代码

4.PTA实验

5.小任务


1.本章学习总结

基本数据类型

  • String类
  • Java的标准输入输出和文件输入输出
  • Java控制执行流程
  • Java数组的使用
  • 类管理机制:包

2.Java Q&A

1.使用Eclipse关联jdk源代码(截图),并查看String对象的源代码?简单分析String对象的设计思路。

  1. 从“Window (菜单项目)”上选择“Preferences (菜单项目)”
  2. 展开“Java (框线项目)”(位于“Preferences”中)
  3. 选择“Installed JREs (框线项目)”(位于“Preferences”中)
  4. 选中当前JRE,并且点击Edit按钮

  5. 展开JRE系统库的第二项,选中展开后的第一项,点击“Source Attachment”按钮

  6. 打开JDK目录,选中src.zip,最后一路确定出去



  7. ctrl+鼠标左键选中某一个类,或者选中类之后按F3,源代码文件弹出,第一问就搞定了

到此为止,只是这一问的第一小问结束了0.0(各位看官不急,我还在码)

String对象的设计思路(我们可以看到在源代码文档里面已经有说了,所以我们要做的仅仅是翻译一下,当然英文不好的同学(比如我这种),可以借助类似金山词霸之类的划译)



我们可以看到就是这点,字符串是常量,往下翻翻我们就会看到private final char value[];,用一个final修饰的字符数组来实现这个字符串的

2.为什么要尽量频繁的对字符串的修改操作应该是用StringBuilder而不是String?

这个东西我们就有讲头了,不妨来看几个String类自带的方法吧。

//这是一个字符串连接的方法
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
//这是一个替换的方法
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */ while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}

在对字符串进行相应修改(例如替换或者是连接)的时候,我们可以发现最后都返回了一个新的字符串常量。所以我们可以想见,如果有大量的字符串拼接的话,那么我们的代码一定会new出很多的String变量,然后又会有很多的垃圾回收。这样的话,代码的效率就会有所降低。

这边来看个代码吧(当然是从Thinking in Java上抄下来的。。。)

public class Concatenation{
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
}

然后使用javap进行反汇编看看发生了什么。。。

Compiled from "Concatenation.java"
public class Concatenation {
public Concatenation();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return public static void main(java.lang.String[]);
Code:
0: ldc #2 // String mango
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String abc
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
19: ldc #7 // String def
21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
24: bipush 47
26: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
29: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
32: astore_2
33: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
36: aload_2
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: return
}

好了,我们看到这个编译器自动引入了一个叫做StringBuilder的东西,,使用它来进行字符串的拼接。这当然是因为StringBuilder更好了,我们刚才说String是immutable的,那这个StringBuilder是专门为字符串修改而生的,在Java SE5引入。所以编译器很聪明的对代码进行了优化。那也就是说,我可以随意使用String,等着代码优化吗?当然不行咯,Java编程思想又给我们举了个反例,来看看。

哦,对了,在String的源文档里面有这样一句话,一样的意思

String concatenation is implemented through the {@code StringBuilder}(or {@code StringBuffer}) class and its {@code append} method.

利用循环来进行字符串的拼接

//输入一个n,从0-n的数字转成字符串进行拼接
public class Main{
public static void main(String[] args) {
int n = 5;
String result1 = "";
for (int i = 0; i < n; i++) {
result1 += i;
}
System.out.println(result1); StringBuilder result2 = new StringBuilder();
for (int i = 0; i < n; i++) {
result2.append(i);
}
System.out.println(result2.toString());
}
}

我们再来反汇编(* * *大法好,虽然我不是很懂)

Compiled from "Main.java"
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1
2: ldc #2 // String
4: astore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_1
9: if_icmpge 37
12: new #3 // class java/lang/StringBuilder
15: dup
16: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
19: aload_2
20: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
23: iload_3
24: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
27: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
30: astore_2
31: iinc 3, 1
34: goto 7
37: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
40: aload_2
41: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
44: new #3 // class java/lang/StringBuilder
47: dup
48: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
51: astore_3
52: iconst_0
53: istore 4
55: iload 4
57: iload_1
58: if_icmpge 74
61: aload_3
62: iload 4
64: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
67: pop
68: iinc 4, 1
71: goto 55
74: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
77: aload_3
78: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
81: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
84: return
}

代码中9-34行是第一个循环(用String的那个),我们可以看到,每次循环开始都会new一个StringBuilder变量,58-71行是第二个循环(用StringBuilder的那个),当然是只在我们一开始new了一个。这个循环更简短,效率当然更高。

3.比较两个字符串的值是否相等?为什么不能用==直接进行比较?

因为用进行比较并不能保证结果总是正确的(假设下面的情况字符串的内容都是相同的),比较的是两个对象的引用

  • 首先如果两个字符串都是以 String xxx = "xxxxx";的方式创建出来的,在第一个字符串如此创建时,JVM就会在字符串池中维护这么一个String的实例,那么以后只要有内容完全相同的字符串,就直接指向这个实例,所以引用会相同

  • 只要有一个是以new的方式创建新的实例,就会创建一个新的对象,当然就有不一样的引用,所以这时候==的两边是不同的引用,当然会返回false

综上所述,我们要对两个字符串进行内容的比较的话,我们要选用一种不是==的方法,那就是equals()方法,看下面的具体实现,没毛病

 public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

但是不是所有的equals()方法都是比较内容,我们这边可以举个小小的反例

class Value{
int i;
} public class EqualsMethod2 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));
}
}

输出结果是false,这是因为equals()的默认行为是比较引用,只是Java类库当中的许多类都已经自己实现了equals()方法,显然我们这边并没有重写这个equals()的方法,所以这边还是只是比较引用

4.尝试使用字符串池的概念解释如下程序段输出结果,并回答这段代码创建了几个字符串对象:

String str1 ="hi", str2="hi";
String str3 = new String(str1);
System.out.println(str1==str2);

最后输出true

分析在前面已经说过了,一共会有两个对象,str1创建的时候,字符串池里面会有一个,也就是str2直接指向字符串池中的那个实例。

然后str3在字符串池外面又new了个

5.Integer i = 100;//100是基本类型,i是引用类型,为什么可以将100赋值给i

public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return public static void main(java.lang.String[]);
Code:
0: bipush 100
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: return
}

同样看到反汇编,我们就可以看到只是调用了Integer类的valueOf的方法而已,然后这个方法是public static Integer valueOf(int i)这样子的,返回一个Integer

6.尝试分析下面代码输出结果

Integer i1 = 127;Integer i2 = 127;
i1 == i2;//true of false?
Integer i1 = 128;Integer i2 = 128;
i1 == i2;//true of false

输出结果分别是truefalse

上回我们刚刚谈到,我们用到了valueOf()这个方法,去给这个Integer进行赋值,so我们需要研究一下这个方法,贴上JDK源码。

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

!这是什么东西,对于不同的范围还区别对待?

是这样的,这个IntegerCache,整数缓存是?再贴源代码(截取部分)

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];

好了,这样我们就知道了,这个IntegerCache是通过Cache数组来实现的,然后-128-127这256个数就被放在了这个数组里,当我valueOf()方法的参数在这个范围内的话,我就将数组中的值返回去,也就是说一开始i1和i2都指向了数组的同一位置,所以当然是相等的咯

然后这个128就相当的尴尬了,因为他正好就在这个范围之外了,所以我们用最朴素的方法创建这个Integer对象,那么就像我们之前所说,通过new来创建的对象具有不同的引用,so传回了false

7.package与javac、 java、 -classpath、 -d

在 com.ibm包中编写 StringUtil类,内有一方法

public static void foo1(){
System.out.println(StringUtil.class+" method:foo1");
}
  • 尝试用命令行进行编译并运行,截图使用javac -d. StringUtil.java使用-d编译选项,建立了相应的文件,将生成的字节码放在了\com\ibm下面

编写Main.java,在第一行加上package edu.jmu,编译后再次生成相应字节码文件

然后再用java命令执行,结果如截图

  • 将生成的StringUtil.class放到d:\lib正确的目录结构下,将Main.class在d:\test正确的目录结构,尝试在命令行下运行,并截图。

    目录结构如下所示:

    • D

      • lib

        • com

          • ibm

            • StringUtil.class
      • test
        • edu

          • jmu

            • Main.class

之前用powershell搞了很久,怼不出来。最后换成cmder就成功了

  • Eclipse中源代码放在哪个目录、class文件放在哪个目录。在Eclipse项目中按一下ctrl+f11就可以直接运行Main,尝试分析背后实现的原理

源代码放在src里面,class放在bin文件夹中。

8.自己在这门课的目标与计划

  • 请描述一下你的技术基础(会什么语言,都写了多少行代码)

    • C 有上万吗,可能有,可能没有吧
    • Matlab 上一千行,应该是有了
    • Python 上百行
  • 一周准备花多少时间在这门课上?一周准备写多少行代码?采用怎样的学习方式?遇到困难打算怎样解决?

    • 具体多长时间不清楚,毕竟还得顾着我的蓝桥杯
    • 一周写个一百多行什么的,还是可以的吧,具体的代码量同样还是不清楚
    • 遇到困难
      • 百度、谷歌……
      • 看书
      • 问老师
      • 放弃,我不搞了,开玩笑的
  • 关于这门课的smart目标

    首先这个是SMART

S pecific:具体的,无二义性的,能描述 “成功” 是什么样的。

M otivating: 目标能激发对目标的兴趣么?实现目标对学生来说说意味着什么?他们会为之自豪么?

A chievable: 能做到么?是挟泰山以超北海?还是把墙角一堆砖头搬走?

R elevant: 和学生来到大学的大方向、目标吻合

T rackable: 能衡量进度的,和有些资料提到的 Measurable 相似。

要不就姑且试试Java web?虽然别人说这都是套框架,可是我连框架都不会套……

这让我想到职业规划的SWOT(S trengths, W eaknesses, O pportunities, T hreats)。那我就分门别类的说下吧。

  • 我觉得对于一门语言来说,怎么算是学成功了呢,应该就是能够使用这门语言真的做一件有实际用途的事情,可能主要是做开发之类的吧(现在还不是很清楚)
  • 分情况,假如我刚开始学编程的时候,会打printf("%d", a + b);我都会很开心。然而我们不可能总是停留在这个层次,我们总是需要向上走
  • 至于可行性,如果暂且把目标放的低一点,做一些简单功能的实现,我觉得还是可以的吧,不能一口吃成一个大胖子,也不能推得太慢吧。
  • 没什么大方向,也没什么具体的目标吧。很惭愧,感觉还是把现在的事情做好了再说。
  • 没试过啊,进度什么的先放着吧,要是凡事都能有个进度条就好了,很可惜并不是

话再说回来,很想在这个学期继续打牢计算机以及数学基础。不然就可以直接去培训机构,三个月上岗,而不用来大学了

9.选做:公交卡里应该还有多少钱?请分析原因

-0.1(元)参考腾讯新闻

可能是无符号浮点数下溢了。

不过……

新闻里说是这台闸机的问题,所以其他的闸机肯定是能正常显示的,那至于这个为什么不对,就不清楚了。

3.使用码云管理Java代码


4.PTA实验

  • 第一题,是函数调用,就是要注意需要sort的数组需要在循环输入选项的代码块外面就创建,如果在sort数组里面临时创建,当然其它选项是找不到的啦
  • 第二题,StringBuilder类的基本使用,就是一开始的时间限制压得很死,所以一会能A,一会又不能A。
  • 第三题,就是要自己去实现一下Comparator,然后就很流畅了
  • 第四题,for循环也可以,就是要一个二维数组,因为数据量不是很大,所以我是直接初始化了
  • 第五题,使用BigDecimal类来实现浮点数的精准计算,当然也可以用数组的方式来实现。不过既然有现成的,就用现成的好了
  • 第六题,枚举的基本使用
  • 第七题,可以用BigInteger实现的东西,就是学会用
  • 第八题,ArrayList的基本使用,相当于数据结构中提到的链表

5.小任务

代码有点丑陋……不过效果还行吧

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner; public class Main {
//用来找第一个不是空格的字符
private static int firstCharNotSpace(String string) {
int i;
for (i = 0; i < string.length(); i++) {
if (string.charAt(i) != ' ') {
break;
}
}
return i;
}
//如果是ABCD或是数字啥的,那么前面有空格就要删
private static Boolean needToDeleteSpace(char ch) {
if (Character.isDigit(ch) || ch >= 'A' && ch <= 'D') {
return true;
}
return false;
}
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("C:/Users/LJL36/Desktop/choice.txt"));
PrintWriter printWriter = new PrintWriter("C:/Users/LJL36/Desktop/output.txt");
int res = 0;//记录有多少道题目 //这边很蠢的先统计了一下题目
while (sc.hasNextLine()) {
String string = sc.nextLine();
if (string.trim().length() == 0) {
continue;
}
int index = firstCharNotSpace(string);
if (Character.isDigit(string.charAt(index))) {
res++;
}
}
printWriter.println(res); //重新打开文件
sc = new Scanner(new File("C:/Users/LJL36/Desktop/choice.txt"));
while(sc.hasNextLine()){
StringBuilder stringBuilder = new StringBuilder(sc.nextLine());
String string = stringBuilder.toString();
//如果是空格串,就跳过
if (string.trim().length() == 0) {
continue;
}
//删空格
int index = firstCharNotSpace(string);
if (needToDeleteSpace(string.charAt(index))) {
stringBuilder.delete(0, index);
} //将答案在后面用pta要求格式输出
index = string.lastIndexOf('。');
if (index != -1 && index != string.length()) {
boolean flag = false;
String string2 = "@[";
for (int i = index + 1; i < string.length(); i++) {
if (Character.isLetter(string.charAt(i))) {
flag = true;
string2 += Character.toUpperCase(string.charAt(i));
}
}
string2 += "](2)"; stringBuilder.delete(index + 1, string.length()); if (flag) {
stringBuilder.append(string2);
}
} stringBuilder.append(" ");
printWriter.println(stringBuilder.toString());
}
sc.close();
printWriter.close();
}
}

下面贴一下最后的运行结果

看的不过瘾的请点下面

回到顶部


最后总是要说句废话什么的,有同学和我说我的排版太丑陋了。嗯……我只能顾上眼前的苟且了,非常感谢偷偷看我博客的同学,可是能不能粉我一下,我也会回粉你们的,谢谢~

201521123091 《Java程序设计》第2周学习总结的更多相关文章

  1. 20145213《Java程序设计》第九周学习总结

    20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...

  2. 20145213《Java程序设计》第二周学习总结

    20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...

  3. 20145213《Java程序设计》第一周学习总结

    20145213<Java程序设计>第一周学习总结 教材学习内容总结 期待了一个寒假,终于见识到了神秘的娄老师和他的Java课.虽说算不上金风玉露一相逢,没有胜却人间无数也是情理之中,但娄 ...

  4. 21045308刘昊阳 《Java程序设计》第九周学习总结

    21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...

  5. 20145330孙文馨 《Java程序设计》第一周学习总结

    20145330孙文馨 <Java程序设计>第一周学习总结 教材学习内容总结 刚开始拿到这么厚一本书说没有压力是不可能的,开始从头看觉得很陌生进入不了状态,就稍微会有一点焦虑的感觉.于是就 ...

  6. 20145337 《Java程序设计》第九周学习总结

    20145337 <Java程序设计>第九周学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC可以 ...

  7. 20145337 《Java程序设计》第二周学习总结

    20145337 <Java程序设计>第二周学习总结 教材学习内容总结 Java可分基本类型与类类型: 基本类型分整数(short.int.long).字节(byte).浮点数(float ...

  8. 20145218《Java程序设计》第一周学习总结

    20145218 <Java程序设计>第一周学习总结 教材学习内容总结 今天下午看了Java学习的视频,感觉很是新奇,之前觉得Java学起来是艰难枯燥的,但通过第一章的学习觉得如果自己可以 ...

  9. 《Java程序设计》第九周学习总结

    20145224 <Java程序设计>第九周学习总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的 ...

  10. 《Java程序设计》第二周学习总结

    20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...

随机推荐

  1. Windows 2008服务器环境PHP连接SQL Server数据库的配置及连接方法

    背景: PHP程序常用的数据库是Mysql数据库,但是由于实际项目需要,要求PHP网站连接SQL Server数据库查询一些必要信息.因此,本文就来给大家介绍一下如何安装及配置PHP扩展,可以实现PH ...

  2. 1.three.js世界的4大要素

    一.三大组件 在Three.js中,要渲染物体到网页中,我们需要3个组建:场景(scene).相机(camera)和渲染器(renderer).有了这三样东西,才能将物体渲染到网页中去. 记住关建语句 ...

  3. easyui&8Jquery ztree树插件

    7Jquery easyui前台UI框架 开发包: 7.1Layout页面布局 将课后资料中后台系统前台页面素材导入项目中 1.导入Jquery,easyui相关js,css文件 <link r ...

  4. vue.js开发环境搭建以及创建一个vue实例

    Vue.js 是一套构建用户界面的渐进式框架.Vue 只关注视图层, 采用自底向上增量开发的设计.Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. 在使用 vue.js ...

  5. Github 开源:使用 .NET WinForm 开发所见即所得的 IDE 开发环境(Sheng.Winform.IDE)【2.源代码简要说明】

    GitHub:https://github.com/iccb1013/Sheng.Winform.IDE 在上一篇文章中,简要的介绍了  Sheng.Winform.IDE 的基本功能和要实现的目标: ...

  6. M4—按键识别

    三.KEY 3.1  初始化 1.相应端口时钟使能 2.配置GPIO为输入模式 3.根据实际电路图 配置浮空输入,不用上下拉 3.2  按键识别 (1)一般按键步骤(延时消抖) 1. 判断相关的管脚是 ...

  7. 设计模式(5)--Builder(建造模式)--创建型

    1.模式定义: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品 ...

  8. javascript-数组的常用方法

    不知大家是否有过跟我类似的经历,就是切图仔刚开始做切图页面的时候,经常调用一些别人写的jquery插件,例如音乐播放器这种需要切换多首音乐的插件.调用的时候就必须有一个音乐队列,而这个队列就是一个数组 ...

  9. fs模块练习

    1.fs+path练习01.判断 当前路径下的public是否存在,不存在则创建02.判断 public下的index.html文件是否存在,不存在则创建 <h1>index</h1 ...

  10. Java WEB工程搭建UEditor

    1. ueditor简介: UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... UEdito ...