• 201521123083《Java程序设计》第二周学习总结


    1. 本周学习总结

    这周我花在java里面的时间就是在做pta和看课本继承,接口和多态这几章的内容。
    在pta上的总结:
    详细的具体在后面pta实验中总结再说,这里先说几点。

    • 借着List和ArrayList理解接口和多态.
    • 研究Strng,StringBuilder,StringBuffer
    • Scanner类的详细使用

    2. 书面作业

    Q1.使用eclipse关联jdk源代码,并查看string对象的源代码(截图)?

    分析string使用什么来存储字符串的?
    分析其构造函数public string(char value[])的实现原理?
    分析public string replace(char oldchar, char newchar)的实现原理,回答string的不可变性在该函数中如何体现?(重点)

    1. 在EclipseMyeclipse中关联源代码 。里面有详细介绍。其实myeclipse默认就有自动关联了。所以当我按照教程去做的时候发现里面已经有了。

    2. private final char value[];由这句可见,它的由字符数组来储存字符串的。并且有final可见,其值为常量,不可变。

     `public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    	}`
    

    先来看Arrays.copyOf

        public static char[] copyOf(char[] original, int newLength) {
                char[] copy = new char[newLength];
                System.arraycopy(original, 0, copy, 0,
                                 Math.min(original.length, newLength));
                return copy;
    }
    

    传入两个参数,旧的字符串数组和新的长度。返回一个跟旧的字符串内容一样,长度不一样的数组。
    而在构造函数里面传入的就是一个字符数组,并且长度等于这个字符数组。
    String其实内部依靠的就是字符数组开储存元素,在这里,其实就是把它的内部数组的值变成传进来的字符串。
    4.

        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;
    	}
    

    我用例子演示下,加入原来字符串是"123456789",要把5变成6
    那么找到要变动位置4
    把位置4之前移进buff,此时buff['1','2','3','4','','',...]
    c=5,判断是不是5,如果是5的话,那么buff[i]就取5,否则取原来的值。

    这里特别能表现String的不可变动,因为不是直接在原来的字符数组里面操作,而是另外新建了一个新的数组,对原来数组的值是不受影响的。。

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

    String是字符常量,其内部不可变。

    String s="123";
    System.out.println(s);
    s+="456";
    System.out.println(s);
    

    但是看这个可能会困惑,这里String明明可以变,
    但是看这里

    String s="123";
    //	System.out.println(s);
    	System.out.println(s.hashCode());
    	s+="456";
    //	System.out.println(s);
    	System.out.println(s.hashCode());
    
    48690
    1450575459
    

    说明了s不是同一个对象。这里我解释一下hashCode()。
    本来我的想法是想要获取对象的内存地址,但是找了好久发现其实jvm是不让我们知道它的地址的,
    但是每个对象都有一个唯一hashCode()。由于唯一性,近视可以来辨别身份。
    所以这里的实现其实是新建一个对象,没修改一个就新建一个对象,,在频繁使用中很耗内存。
    而我们来看StringBuilder

    StringBuilder s =new StringBuilder("123");
    System.out.println(s.hashCode());
    s.append("456");
    System.out.println(s.hashCode());
    
    2007267255
    2007267255
    

    这是我电脑上的。所以StringBuilder就不用频繁建对象

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

    先说和equal的区别,其实两个是一样的。equal和toString,hashcode都Object中的类,由于一切类归根揭底
    就是继承object,,所以任何类都有equal。也可以重写。
    默认情况下
    和equal的作用但是传入两个参数的hashcode一不一样,由于hashcode的一致性,所以他们的作用等效于判断
    两个对象一不一样。
    但是equal在String和Integer里面被重写了。它新的作用是判断两个对象的内容一不一样。

    String s=new String("1");
    String s1=new String("1");
    System.out.println(s==s1);
    System.out.println(s.equals(s1));
    
    false
    true
    

    但是String还有一种特殊情况,,就是它初始化的时候如果不用new,如s="123",这样的话,引用所指向的值是在字符串常量池里面,并且为了节省空间,常量池里面字符串唯一,,所以这种方式初始化的

    内容相同的字符串引用,,他所指向的是同一个,这样避免每一个都新建一块堆空间浪费空间。
    String s="1";
    String s1="1";
    System.out.println(s==s1);
    System.out.println(s.equals(s1));
    

    都是true

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

    string str1 =“hi“, str2=“hi“;
    string str3 = new string(str1)
    system.out.println(str1==str2);
    

    我画张图

    其中A为常量池

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

    jdk5.0之后支持的自动装箱,拆箱

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

    integer i1 = 127;integer i2 = 127;
    i1 == i2;//true of false?
    integer i1 = 128;integer i2 = 128;
    i1 == i2;//true of false
    第一个true
    第二个false
    看源代码
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    IntegerCache.low是0 , IntegerCache.high是127
    如果大于128,就新建一个对象,在第三题种说过,==用于判断两个对象是不是同一个对象

    Q7

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

    7.3 Eclipse中源代码放在哪个目录、class文件放在哪个目录?在Eclipse项目中按一下Ctrl+F11就可以直接运行Main,当按下Ctrl+F11时,到底在哪个目录下执行了什么样的java命令?
    源代码:workplace\project\src
    class:workplace\project\bin
    在src\edu\jmu\这个目录下,执行 javac -d workpace\project\bin -classpath workpace\project\bin Main.java
    

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

    请描述一下你的技术基础(会什么语言,都写了多少行代码)
    一周准备花多少时间在这门课上?一周准备写多少行代码?采用怎样的学习方式?遇到困难打算怎样解决?
    关于这门课的smart目标参考链接

    3. 使用码云管理Java代码

    在码云的项目中,依次选择“统计-Commits历史-设置时间段”,然后搜索并截图

    刚刚提交的,但是不是都是今天做的,平时做完没提交,要用的时候才从pta里面找出来提交。。下次做完就提交上去。

    4. PTA实验

    *5-1 jmu-Java-02基本语法-01-综合小测验*  
    >其实每个问题都不难,但是结合在一起常常出问题。提交的时候出现的第一个问题就是switch里面String是jdk7才引进的,所以出问题了,还有就是Scanner的问题,会出现有些scanner读错地方了,迄今为止这个问题尚未解决。
    
    *5-3 jmu-Java-02基本语法-03-身份证排序*  
    这一题我采用的方法是新建一个class Id.
    
    
    class Id implements Comparable<Id> {
    	public String name;
    	public int birthday;
    	public String print;
    	public Id(String name) {
    		// TODO Auto-generated constructor stub
    		this.name=name;
    		//350623 1997 11 28 511x
    		this.birthday=Integer.parseInt(name.substring(6,14));
    		this.print=name.substring(6, 10)+"-"+name.substring(10,12)+"-"+name.substring(12,14);
    	}@Override
    	public int compareTo(Id o) {
    		// TODO Auto-generated method stub
    		return birthday-o.birthday;
    	}
    
    }
    }
    其中新学到的就是实现借口,重写compareTo,让类也可以参加排序
    *5-6 jmu-Java-02基本语法-06-枚举*  
    有时候switch和枚举一起用特别方便
    

  • 相关阅读:
    sed 命令
    find命令详解
    texlive、
    linux source命令与export命令的区别
    vscode浏览器打开html vscode修改默认浏览器
    npm install说明
    有关必须组件化的需求
    日志文件上传的时机
    TypeScript vs. C#: LINQ
    JavaScript 运行机制详解:再谈Event Loop
  • 原文地址:https://www.cnblogs.com/daikersec/p/6502613.html
Copyright © 2020-2023  润新知