java学习笔记: 基础知识: day09: Object, String, StringBuilder,字符串的一些常用方法

====
day09
java学习笔记: 基础知识: day09: Object, String, StringBuilder,字符串的一些常用方法

一、API的概述
当你想学习一个API的时候,可以查看API文档。
不想看API文档的话,可以直接看源代码。建议有时间的话,还是要好好研究一下java JDK的源代码。
(一)Object和toString方法
1.Object是类层次结构的根类,所有的类都直接或者间接地继承自Object。
在eclipse里导入JDK的源代码class包:鼠标放在class的名字上,1.ctrl+鼠标左键,然后选“Change Attached Source...”。2.External location = JDK安装目录下的src.zip

2.构造方法:Object();

3.重要方法:
(1)toString();//用字符串的形式表示对象。如果我们没有覆盖override toString()方法,返回的是类的全路径类名加上@再加上对象的地址值。如果覆盖后,返回的是对象的属性值。
源代码如下:
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

(2)equals();//比较两个对象是否相等。如果没有覆盖override的话,比较的是两个对象的地址值(地址值用HashCode来表示)。覆盖后可以比较两个对象的属性值。

4.直接输出对象名,输出底层调用的是该对象的toString()。
查看API后,发现所建议所有子类都覆盖toString()。
It is recommended that all subclasses override this method.


(二)equals方法
equals方法
1.功能:比较两个对象是否相等。如果没有覆盖override的话,比较的是两个对象的地址值。覆盖后,可以比较两个对象的属性值。

2.==:
  (1)可以比较基本数据类型,比较基本数据类型的时候,比较的是基本数据类型的值是否相同。
  (2)可以比较引用数据类型,比较引用数据类型的时候,比较的是引用数据类型的地址是否相同。

3.如果想比较引用对象的内容是否相同,覆盖override public boolean equals(Object obj){...}

4.s1.equals(s2);//this=s1,哪个对象调用的equals,this就是谁。obj=s2,被调用时的参数是哪个对象,obj就是谁。

5.覆盖equals方法
业务流程:
(1)
A.地址值
B.对象是否为空null
C.是否是同一个类的对象
(2)
A.obj向下转型,开始比较各个属性值。
B.比较基本数据类型
C.比较引用数据类型:a.对象是否为null。b.值。

具体代码:
public boolean equals(Object obj){
  //调用:cat.equals(cat2);
  //this: cat
  //obj: cat2
  if(this == obj) return true;//比较cat和cat2的地址是否相同。如果相同,说明它们是同一个对象,肯定相同。
  if(obj == null) return false;//看cat2是否为null。cat肯定不为null。如果cat为null,会报NullPointerException,根本走不到这个方法里。
  if(getClass() != obj.getClass()) return false;//看两个对象cat和cat2是不是同一个类的对象。如果不是同一个类的对象,说明不是同一个物种,直接return false,没有比较的必要。
  Cat other = (cat)obj;//把obj向下转型,为什么呢?因为下面要比较cat和cat2的属性值。如果不向下转型,还是obj的话,是不能获取cat2的属性值的。
  if(age != other.age) return false;//由于age属性是基本数据类型,可以直接用关系运算符比较。
  if(name == null){//看cat/this的name属性是否为null。这里为什么要判断name是否为null呢?如果name为null,两边比较name的属性值的时候,会报NullPointerException。
    if(other.name != null) return false;//如果this.name为null,但是cat2.name不为null,说明它们不相同,直接返回false。
  }else if(!name.equals(other.name)) return false;//比较this.name和cat2.name的值是否相同,如果不同,直接返回false。
  return true;
}//the end


二、String类的概述和介绍
1.String:代表字符串类。
字符串是由多个字符组成的一串数组。
字符串的本质就是一个字符数组。

2.构造方法
String(String original):  把字符串数据封装成字符串对象。String s=new String("Hello");
String(char[] value): 把字符数组的数据封装成字符串对象。char[] chs={'H','E','L','L','O'};String s=new String(chs);
String(char[] value, int index, int count): 把字符数组的一部分数据封装成字符串对象。String s=new String(chs, 1, 2);

3.最常用的方式-直接赋值:String s="hello";

4.String类创建对象的特点
  (1)通过构造方法创建对象。通过构造方法创建的字符串对象是在堆内存中。
  (2)通过直接赋值的方式创建对象。通过直接赋值的方式创建的字符串对象,是在方法区的常量池中。(推荐用这个方式)
字符串的内容存储在方法区的常量池。这样做事为了方便字符串数据的复用。
图片:见“String创建对象的特点.bmp”

java学习笔记: 基础知识: day09: Object, String, StringBuilder,字符串的一些常用方法

 

核心代码:
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";
System.out.println(s1 == s2);//false  对象的比较,它们比较的是内存中的地址。
System.out.println(s1 == s3);//false
System.out.println(s3 == s4);//true

完整代码:
package com.itheima_02;
/*
 * String类创建对象的特点:
 *   A:通过构造方法创建对象
 *   B:通过直接赋值的方式创建对象
 * 这两种方式的创建是有区别的。
 * 通过构造方法创建的字符串对象是在堆内存。
 * 通过直接赋值的方式创建的字符串对象是在方法区的常量池。
 */
public class StringDemo {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        
        String s3 = "hello";
        String s4 = "hello";
        
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s3);//false
        System.out.println(s3 == s4);//true
    }
}

5.一些比较好的String操作代码
题目一.模拟用户登录,给三次机会
1.定义两个字符串对象,设定用户名和密码
2.键盘录入用户名和密码
3.比较录入的数据和设定的用户名和密码是否相同,并给出提示

//file name: Test01.java
package com.itheima.back;

import java.util.Scanner;

/*
 * 模拟用户登录,给三次机会
 * 
 *     1.定义两个字符串对象,设定用户名和密码
 *     2.键盘录入用户名和密码
 *     3.比较录入的数据和设定的用户名和密码是否相同,并给出提示
 */
public class Test01 {
    public static void main(String[] args) {
        String user = "woaixuexi";
        String pass = "woaixuexi";
        
        Scanner sc = new Scanner(System.in);
        
        for (int i = 0; i < 3; i++) {
            //ctrl + 2 松手+ L
            System.out.println("请输入用户名");
            String username = sc.nextLine();
            System.out.println("请输入密码");
            String password = sc.nextLine();
            
            if(username.equals(user)&&password.equals(pass)){
                System.out.println("登录成功");
                break;
            }else{
                if(2-i==0){
                    System.out.println("您的账号被锁定,请联系管理员");
                }else{
                    System.out.println("登录失败,您还有"+(2-i)+"次机会");
                }
            }
        }
        
    }

}
----


题目二.遍历字符串,即获取字符串中的每一个字符
String s = "16JKM13";
for(int i = 0; i < s.length(); i++){
  char ch = s.charAt(i);//获取字符串s中的某个索引位置的字符串元素
  if(ch >= '0' && ch <= '9'){//判断字符是不是数字
    System.out.println(ch);//比较的是ASCII码值
  }
}
//ch >='A' && ch <= 'Z'   大写字母
//ch >='a' && ch <= 'z'   大写字母
//ch -= ('a' - 'A');  从小写字母变成大写字母   'a'-'A'=32,  'A'=65,  'a'=97
----

题目三.字符串的拼接
int[] arr = {11,22,3,4,5};
String s = "[";
for(int i = 0; i < arr.length; i++){
  if(i == arr.length - 1){
    s += arr[i];
  }else{
    s += arr[i] + ", ";
  }
}
s += "]";
System.out.println(s);
//字符串拼接s+=...  因为String concat方法重载overload了
----


题目四.字符串反转  abc-->cba
String s = "abc";
String s_new = "";//空串
for(int i = s.length - 1; i >= 0; i--){
  char ch = s.charAt(i);
  s_new += ch;
}
System.out.println(s_new);
----


三、StringBuilder
图片:见“String对字符串进行拼接.bmp”

java学习笔记: 基础知识: day09: Object, String, StringBuilder,字符串的一些常用方法


代码:
String s = "hello";
s += "world";
System.out.println(s);

我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象。既耗时又浪费空间。而StringBuilder就可以解决这个问题。

图片:见“StringBuilder对字符串进行拼接.bmp”

java学习笔记: 基础知识: day09: Object, String, StringBuilder,字符串的一些常用方法


代码:
StringBuilder sb = "hello";
sb.append("world");
System.out.println(sb);


1.StringBuilder:是一个可变的字符串类,内容是可变的,非常适合做字符串拼接操作。
String:内容是固定的,字符串都是常量。

2.构造方法
public StringBuilder();//创建一个空的字符串
public StringBuilder(String str);//把str这个字符串转成了StringBuilder对象

3.一些功能
  (1)添加功能:public StringBuilder append(任意类型);//添加数据,并返回对象本身
链式编程:sb.append("hello").append("world");//反着看,这是一个方法,方法由对象调用;正着看,对象调方法,返回的是一个对象。
  (2)反转功能:public StringBuilder reverse();
  (3)删除功能:public StringBuilder delete(int start, int end);//移除此序列的子字符串中的字符

4.StringBuilder和String的相互转换
StringBuilder-->String: public String toString();//通过toString()就可以把StringBuilder转换为String
String-->StringBuilder: public StringBuilder(String s);//通过构造方法就可以把String转换为StringBuilder

5.练习:字符串反转
思路:String-->StringBuilder-->reverse-->String
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuilder sb = new StringBuilder(s);
sb.reverse();
String s2 = sb.toString();

6.StringBuffer和StringBuilder:
举例:多人吃同一盘肉
StringBuilder:线程不安全,效率高。
StringBuffer:线程安全,效率低一些。
====


四、字符串的一些常用方法
----
附上String的源代码   java.lang.String.java
具体路径:jdk1.7.0_72\src\java\lang

我不知道怎么在文章里贴附件,网友们可以找jdk的源代码zip包,然后在里面的java.lang路径下找String.java这个文件。

字符串方法需要接收返回结果。
public char charAt(int index);//返回字符串中某个索引位置的字符元素
public boolean endWith(String small);//判断字符串是否已小字符结尾
public boolean equals(Object anObject);//判断两个字符串是否相等
public boolean equalsIgnoreCase(String anotherString);//判断两个字符串是否相等,忽略大小写
public int indexOf(int ch);//获取字符或小字符串在大字符串中的位置,不存在的话返回-1
public int length();//返回字符中元素的个数,字符串的长度
public String replace(CharSequence small, CharSequence replace);//把大字符串中的小字符串替换成replace,替换所有
例如:
  String s = "11, 22, 33, 44";
  String replace = s.replace(",", "-");
  System.out.println(replace);//11-22-33-44
public String replaceFirst(String small, String replace);//把大字符串中的小字符串替换成replace,只替换第一次出现的
例如:
  String s = "11,22,33,44";
  String replace = s.replaceFirst(",", "-");
  System.out.println(replace);//11-22,33,44
public String[] split(String small);//用小字符串切割大字符串
例如:
  String s = "11,22,33,44";
  String[] split = s.split(",");
  for(int i = 0; i < split.length; i++){
    System.out.println(split[i]);
  }
public boolean startsWith(String prefix);//判断大字符串是否以小字符串开头
public String subString(int beginIndex);//截取字符串,从索引beginIndex开始,截取到最后
例如:
  String s = "abcdefg";
  String subString = s.subString(3);
  System.out.println(subString);//defg
public String subString(int beginIndex, int endIndex);//截取字符串,从beginIndex开始,到endIndex结束,包含beginIndex,不包含endIndex
例如:
  String s = "abcedfg";
  String subString = s.subString(1, 4);
  System.out.println(subString);//bcd
public char[] toCharArray();//把字符串编程字符数组
例如:
  String s = "abcdefg";
  char[] chs = s.toCharArray();
  for(int i = 0; i < chs.length; i++){
    System.out.println(chs[i]);
  }
public String toLowerCase();//把字符串中的大写字母变成小写字母
例如:
  String s = "dfkdjALSJDLJF";
  s = s.toLowerCase();
  System.out.println(s);
public String toUpperCase();//把字符串中的小写字母变成大写字母
例如:
  String s = "dfkdjALSJDLJF";
  s = s.toUpperCase();
  System.out.println(s);
public static String valueOf(boolean b);//把各种类型的数据转成字符串
例如:
  String valueOf = String.valueOf(234);
  System.out.println(valueOf);//234

 

 

小结:
学习一个类,要掌握它的:
1. 这个类的基本功能是什么,能解决什么问题。
2. 构造方法
3. 一些常用的方法

====