IDEA中想要从使用方法的地方或者从接口中的方法,跳转到方法具体实现的地方:ctrl + alt + 鼠标左键。
想要搜String类的成员方法:Ctrl+F12,然后输入:equals,即可找到String类中的equals()方法。
String类:是用来描述字符串 字符串是由多个字符组成的一串字符数据(字符序列)
String构造方法:
-
public String() 空字符串 “” 了解
-
String(byte[] bytes)
//利用字节数组,创建字节数组所表示的字符串
// 1. 字符 -> 数值形式 ‘a’ -> 97
// 2. 所以可以用多个字节值,表示多个字符——>即字符序列 public -
public String(byte[] bytes,int offset,int length)
//利用字节数数组的一部分,创建字符序列, 从byte数组的offset开始的length个字节值 -
public String(char[] value)
//利用一个字符数组创建字符数组,代表的字符序列 -
public String(char[] value,int offset,int count)
// 创建value字符数组中,从第offset位置开始的count个字符,所代表的字符串对象 -
public String(String original) 知道即可
public class Demo01Basic01 {
public static void main(String[] args) {
// public String()
String str = new String(); // 和 str引用变量不为null
String s = "";
// public String(byte[] bytes)
// 'a' 'b' 'c' 'd' 'e'
byte[] byteStr = {97, 98, 99, 100, 101};
s = new String(byteStr);
//System.out.println(s);
// public String(byte[] bytes,int offset,int length)
// 创建"bcd"
s = new String(byteStr, 1, 3);
//System.out.println(s);
// public String(char[] value)
char[] chars = {'a', 'b', 'c', 'd', 'e'};
s = new String(chars);
//System.out.println(s);
//public String(char[] value,int offset,int count)
s = new String(chars, 1, 3);
System.out.println(s);
//public String(String original)
String originStr = "zhangsan";
String newStr = new String(originStr);
System.out.println(newStr);
}
}
String 类中,覆盖了Object类的equals方法,String的equals方法比较的是字符串内容,而==比较的是两个引用是否指向同一对象。
System.out.println("".equals(str));
····························································································································································································································
java语言字符串的特征:字符串是常量,它的值在创建之后不能更改
图一:字符串创建之后不能被修改
String s = “hello”; s += “world”; 问s的结果是多少?
这个答案很容易知道,但jvm具体帮我们做了些什么?看图
图二:字符串的字面值常量的存储
面试题
String s = new String(“hello”)和String s = “hello”;的区别?
第一句代码:对应了jvm中的两个字符创对象
第二句代码:对应了jvm中一个字符串对象
练习题:看程序写结果:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); //true
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4); //false
System.out.println(s3.equals(s4)); //true
String s5 = "hello";
String s6 = "hello";
System.out.println(s5==s6); //true
System.out.println(s5.equals(s6)); //true
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == (s1+s2)); //false
System.out.println(s3.equals(s1+s2)); //true
System.out.println(s3 == ( "hello" + "world"));// ???? 不是false而是true
System.out.println(s3.equals("hello"+"world"));//true
关于System.out.println(s3 == (s1+s2)); //false的解释:
关于System.out.println(s3 == ( “hello” + “world”));// ??? 不是false而是true的解释:
字符串拼接何时会在堆上,创建新的字符串对象,何时不会呢?
- 当参与字符串拼接的两个字符串中,至少有一个是以字符串的引用变量的形式出现,此时拼接运算,必然会在堆上创建新的字符串对象
s1 + s2和s1 + “hello” - 只有参与字符串拼接运算两个字符串,都是字符串常量的时候,此时不会在堆上创建新的字符串对象,而是直接拼接。
字面值常量的值不会变的,所以编译器就放心大胆的直接做拼接
····························································································································································································································
String类的的判断功能:
- boolean equals(Object obj) //比较字符串内容
- boolean equalsIgnoreCase(String str) //比较字符串内容,但是忽略字符串大小写
- boolean contains(String str) // 判断当前字符串中是否包含,参数字符串
- boolean startsWith(String str) // 当前字符串是否以参数字符串开头
- boolean endsWith(String str) // 当前字符串是否以参数字符串结尾
- boolean isEmpty() //判断字符串是否为空串
String s = null; //s是一个空引用,表示s没有指向任何一个对象。在这个引用变量s上调用任何String类型的方法都会报错:空指针异常
String s = ""; //s是一个空串,""字符串对象存在于字符串字面值常量池中,引用类型s指向字符串字面值常量池中的""对象。
····························································································································································································································
一定要了解清楚:数组的length属性、String的length()方法,和集合Collections的size()方法
String类的的获取功能:
- int length() //返回当前字符串中包含的字符个数
- char charAt(int index) // 获取字符串指定位置的字符(字符串中的字符,从左到右,从0开始编号)
- int indexOf(int ch) // 在当前字符串中,查找参数字符,如果当前字符串中存在,则返回首次出现的位置,若不存在则返回-1
- int indexOf(String str) //在当前字符串中,查找参数字符串首次出现的位置如果找到返回,参数字符串首次出现的首字母的位置,否则返回-1
- int indexOf(int ch,int fromIndex) // 指定从字符串的fromIndex位置开始,向后查找指定字符,找到返回其从formIndex开始,首次出现的位置,否则返回-1
- int indexOf(String str,int fromIndex) // 指定从字符串的fromIndex位置开始,向后查找指定字符串,找到返回其从formIndex开始,首次出现的位置,否则返回-1
- public int lastIndexOf(int ch) //返回指定字符在此字符串中最后一次出现处的索引
解释:首次出现的位置:
String str = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
String substr = "java";
System.out.println(str.indexOf(substr,5)); //输出16,16表示s的总位置
- String substring(int start) //生成当前字符串的子串,字串的取值是原字符串的[start, length()-1]
- String substring(int start,int end) //生成当前字符串的子串,字串的取值是原字符串的[start, end)
····························································································································································································································
String类的的转换功能:
- byte[] getBytes() // 获取表示一个字符串中,多个字符对应多个字节值
- char[] toCharArray() // 获取表示一个字符串中,多个字符对应多个字符
- static String valueOf(char[] chs) //把一个字符数组转化成一个字符串
- static String valueOf(int i) // 把一个整数值,转化成其字符串表示形式
- String toLowerCase() // 把一个字符串的所有字符转化成小写,返回该新的字符串对象
- String toUpperCase() // 把一个字符串的所有字符转化成大写,返回该新的字符串对象
- String concat(String str) 完成字符串拼接,了解即可
注:IDEA中连续按两下Shift,就能跳出一个搜索框,这个搜索框是查找类的
····························································································································································································································
String类的替换功能
- String replace(char old,char new) // 在新的字符串中,用新(new)字符,替换旧(old)字符
- String replace(String old, String new) //在新的字符串中,用新的字符串(new), 替换旧(old)字符串
String类去除空字符串
String trim() //在新的字符串中,去掉开头和结尾的空格字符
String类的比较功能
int compareTo(String str)
int compareToIgnoreCase(String str)
- 字符串的大小如何比较?
按照字典序,比较字符串的大小。字典序原本的含义实质,英文单词在字典中出现的先后顺序
(在字典中,先出现的字符串小,后出现的字符串大)
具体到编程语言,是根据两个字符串字符串从左往右数,第一个对应位置的不同字符,来决定两字符串的大小
compareTo几乎就是按照字典序,来比较两个字符串大小的
字符串对象.compareTo(字符串对象)
对于CompareTo方法:
String类实现了一个
interface Comparable {
int compareTo(String anotherStr)
}
该接口,定义了一种比较规则,该规则规定:
- 对于大于这种比较结果 > 0 表示大于关系
- 对于小于这种比较结果 < 0 表示小于关系
- 对于等于这种比较结果 0 表示相等关系
Comparable接口:
Comparable接口的成员方法:CompareTo(T object);
String类实现了Comparable接口,String类中的CompareTo方法源码:
····························································································································································································································
····························································································································································································································
什么是异常?
简单来说异常就是用来表示Java程序运行过程中的错误(信息)
Java异常机制的由来:
- C语言时代的错误处理(不好,程序的自觉性)
- Java的基本理念:尽量把一切错误,摒弃在jvm之外,最好在程序之前发现程序错误(编译器)。但是,很遗憾,有一部分错误,是编译器可以在程序运行前帮我们发现的,但是还有一些错误,是java程序不运行,编译器发现不了
- 错误恢复机制(java异常处理机制)
java语言,退而求其次,可以让java程序运行的时候出错,
但是同时,java语言本身提供了一种通用的错误处理机制 ——> 异常处理机制
异常处理机制:异常的发现,和异常的处理(通过一致性的错误报告模型)
Java异常机制的实质,就是提供了一致性的错误报告模型,使得类的构建者和使用者之间可以进行可靠的沟通
一致性的错误报告模型:
简单来说,就是一旦发生错误,就把该错误信息,层层向上报告,如果上层知道怎么处理这个错误,上层可以捕获该错误信息,并处理,如果上层不知道该怎么处理,可以将错误继续向上报告。最上层上jvm层。
我的理解:
运行,首先进入main方法,再进入test()方法,创建CallClass对象,并调用其call()方法,jvm发现call()方法发生异常,就向上一层调用call()的地方:int call = callClass.call();报告异常的具体信息。如果它处理不了,就向test()方法报告异常的具体信息,如果处理不了,就向main方法报告错误信息,如果处理不了,交给jvm处理。如果中间有一层用了异常处理机制,如try—catch,处理了异常,就不用向上报告了。
public class Demo01Basic {
public static void main(String[] args) {
test();
}
public static void test() {
CallClass callClass = new CallClass();
int call = callClass.call();
//做错误处理:
if (call == -1) {
return;
}
//正常的执行逻辑
}
}
class CallClass {
/*
口头约定,当该方法返回-1的时候,说明该方法没有正常执行,
否则说明返回一个int类型的计算结果
*/
public int call() {
return 0;
}
}
····························································································································································································································
根据java程序在运行过程中,根据程序运行时错误的严重程度,异常可分为:
Exception:在程序中可能能够处理的错误
Error:程序层面无法处理的错误
对于Exception,根据错误处理方式的不同
编译时异常(Checkable Exception)
可预见的,语法层面强制在代码编写时处理
运行时异常(Runtime Exception)
不可预见的,不要求在编写代码时必须处理
异常分三类:
骑车去旅行:
Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是班长能够立马解决的。
Exception:出门前,班长要看看车轮子以及车链子等是否还在
RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路
1,编译时异常
除了RuntimeException及其子类,Exception中所有的子类都是,这种异常必须要处理,要不编译通不过
2,运行是异常
RuntimeException及其子类都是,这种异常不用处理,编译会通过,不过这样的程序会有安全隐患,遇到这种异常是需要改代码的
可以发现,Exception中专门有一个类叫:Runtime Exception(运行时异常),其他类都属于:Checkable Exception(编译时异常)。
关于Error:
Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。大多数这样的错误都是异常条件。虽然 ThreadDeath 错误是一个“正规”的条件,但它也是 Error 的子类,因为大多数应用程序都不应该试图捕获它。
在执行该方法期间,无需在其 throws 子句中声明可能抛出但是未能捕获的 Error 的任何子类,因为这些错误可能是再也不会发生的异常条件。
····························································································································································································································
作业:
1.回文字符串
2.
package com.cskaoyan;
/**
* @author shihao
* @create 2020-04-24 11:26
* <p>
* <p>
* 2. 统计大串中小串出现的次数
* 举例:在字符串” woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun”中java出现了5次
*/
public class Homework02 {
public static void main(String[] args) {
String str = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun";
String substr = "java";
System.out.println(str.indexOf(substr,5)); //输出16,16表示s的总位置
System.out.println(count(str, substr));
}
public static int count(String str, String substr) {
int count = 0;
int i = 0;
while (true) {
i = str.indexOf(substr, i) + 1;
//i == 0;即:str.indexOf(substr, i)==-1,表示str中i之后没有出现substr
if (i == 0)
break;
count++;
}
return count;
}
}
老师答案: