API
4、常用类
类 Object
是类层次结构的根类。每个类都使用Object
作为超类。所有对象(包括数组)都实现这个类的方法。
public int hashCode():返回该对象的哈希码值。哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值。你可以理解为地址值。
public final Class getClass():表示此对象运行时类的 Class
对象。
Class类的方法:public String getName():以 String 的形式返回此 Class 对象所表示的实体
示例:
public class StudentDemo { public static void main(String[] args) { Student s1 = new Student(); System.out.println(s1.hashCode()); Student s2 = new Student(); System.out.println(s2.hashCode()); System.out.println("-----------------"); Student s = new Student(); Class c = s.getClass(); String str = c.getName(); System.out.println(str); //链式编程 String str2 = s.getClass().getName(); System.out.println(str2); } } public class Student extends Object{ }
运行结果:
public String toString():返回该对象的字符串表示。
public class StudentDemo { public static void main(String[] args) { Student s = new Student(); System.out.println(s.hashCode()); System.out.println(s.getClass().getName()); System.out.println("--------------------"); System.out.println(s.toString());// cn.itcast_02.Student@42552c System.out.println("--------------------"); System.out.println(s); } } public class Student{ }
、
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。这个方法,默认情况下比较的是地址值。比较地址值一般来说意义不大,所以我们要重写该方法。
之前我们用过“==”,对于基本数据类型来说,“==”比较的就是值是否相同;对于引用数据类型来说,“==”比较的是地址值是否相同。
public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } } public class StudentDemo { public static void main(String[] args) { Student s1 = new Student("classmate",22); Student s2 = new Student("king", 23); Student s3 = new Student("classmate",22); Student s4 = s1; //对引用数据类型来说,“==”比较的是地址值 System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s1 == s4); System.out.println("--------------"); //equals只能比较引用数据类型 System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3)); System.out.println(s1.equals(s4)); } }
运行结果:
现在来复写下equals方法。首先要知道String类复写了Object类的equals方法,使得该方法用来比较字面值。
public class Student { private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public boolean equals(Object obj){ if(this == obj){ //如果Student类的对象的地址值和传进来的地址值相同,则返回true return true; } //instanceof用来判断该对象名是否是该类名一个对象 if(!(obj instanceof Student)){ return false; } Student s = (Student)obj; return this.name.equals(s.name) && this.age==s.age; } }
注意事项:但是开发时equals还是自动生成
protected Object clone():创建并返回此对象的一个副本。
如果在没有实现 Cloneable
接口的实例上调用 Object 的 clone 方法,则会导致抛出CloneNotSupportedException
异常。所以要clone的对象所属的类一定要实现Cloneable接口。
public class StudentDemo { public static void main(String[] args) throws CloneNotSupportedException { //创建学生对象 Student s = new Student(); s.setName("classmate"); s.setAge(22); //克隆学生对象 Object obj = s.clone(); Student s2 = (Student)obj; System.out.println(s.getName()+"---"+s.getAge()); System.out.println(s2.getName()+"---"+s2.getAge()); } } public class Student implements Cloneable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }运行结果:
public boolean hasNextXxx():判断键盘所输入的数据是否为Xxx类型,是的话返回true。
public Xxx nextXxx();将输入信息的下一个标记扫描为一个Xxx类型数据。
import java.util.Scanner; /* * Scanner:用于接收键盘录入数据 * public boolean hasNextXxx():判断是否是某种类型的元素 * public Xxx nextXxx():获取该元素 * * 用int类型数据举例 * public boolean hasNextInt() * public Int nextInt() */ public class ScannerDemo { public static void main(String[] args) { //创建对象 Scanner sc = new Scanner(System.in); //获取数据 if(sc.hasNextInt()){ int x = sc.nextInt(); System.out.println("x:"+x); } else{ System.out.println("您输入的数据有误"); } } }
public int nextInt():获取一个int类型的值
public String nextLine():获取一个String类型的值
需求:先获取一个int类型的数据,再获取一个String类型的数据
import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { // 创建对象 Scanner sc = new Scanner(System.in); //先获取一个int类型,再获取一个String类型 int a = sc.nextInt(); String s = sc.nextLine(); System.out.println("a:" + a + ",s:" + s); System.out.println("-----------"); } }
运行结果:
分析:输入int类型数据5后,按下空格就直接弹出运行结果了,也就是说无法输入字符串类型的数据。
解决方法:
1、先获取一个数值后,在创建一个新的键盘录入对象获取字符串。
2、把所有的数据都先按照字符串获取,然后要什么,你就对应的转换为什么。
现在使用办法一来实现
import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { // 创建对象 Scanner sc = new Scanner(System.in); //先获取一个int类型,再获取一个String类型 //int a = sc.nextInt(); //String s = sc.nextLine(); //System.out.println("a:" + a + ",s:" + s); //System.out.println("-----------"); int a = sc.nextInt(); Scanner sc2 = new Scanner(System.in); String s = sc2.nextLine(); System.out.println("a:" + a + ",s:" + s); } }
public String():空构造
public String(byte[] bytes):把字节数组转成字符串
public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串
public String(char[] value):把字符数组转成字符串
public String(char[] value,int index,int count):把字符数组的一部分转成字符串
public String(String original):把字符串常量值转成字符串
public class StringDemo { public static void main(String[] args) { // public String():空构造 String s1 = new String(); System.out.println("s1:" + s1); System.out.println("s1.length():"+s1.length()); System.out.println("-----------------"); //public String(byte[] bytes):把字节数组转成字符串 byte[] bys = new byte[]{97,98,99,100,101}; String s2 = new String(bys); System.out.println("s2:" + s2); System.out.println("s2.length():"+s2.length()); System.out.println("-----------------"); //public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串 //我想得到字符串“bcd” String s3 = new String(bys,1,3); System.out.println("s3:" + s3); System.out.println("s3.length():"+s3.length()); System.out.println("-----------------"); //public String(char[] value):把字符数组转成字符串 char[] chs = new char[]{'a','b','c','d','爱','我'}; String s4 = new String(chs); System.out.println("s4:" + s4); System.out.println("s4.length():"+s4.length()); System.out.println("-----------------"); //public String(char[] value,int index,int count):把字符数组的一部分转成字符串 String s5 = new String(chs,2,4); System.out.println("s5:" + s5); System.out.println("s5.length():"+s5.length()); System.out.println("-----------------"); //字符串字面值"abc"也可以看成是一个字符串对象。 String s7 = "abcde"; System.out.println("s7:"+s7); System.out.println("s7.length():"+s7.length()); } }
特点:一旦赋值,就不能改变
怎么理解呢?
/* * 字符串特点:一旦赋值,就不能改变。 */ public class StringDemo { public static void main(String[] args) { String s = "hello"; s += "world"; System.out.println("s:" + s); } }运行结果:
分析:字符串直接赋值的方式是先到字符串常量池里去找,如果有就返回,如果没有就创建并返回。首先将"hello"赋值给字符串的引用s,会现在常量池里找,没有发现,所以创建了“hello”字符串在常量池里,当执行“s += "wrold";”时,会在常量池里创建“world”字符串,然后拼接成一个新的字符串“helloworld”在常量池里,并将地址值返回给引用s。也就是说,”hello“字符串并没有发生改变,只是引用变量s指向了新创建的字符串对象"helloworld"。
面试题1:
public class StringDemo { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); } }
运行结果:
原因分析:字符串创建的时候,有一个字符串常量池,s1创建后,"abc"放入其中。s2创建的时候,"abc"已经存在于字符串常量池中,故引用变量s2直接指向了已经存在的"abc"字符串对象,故s1和s2的地址值相同,故s1==s2。
面试题2:String s = new String(“hello”)和String s = “hello”有什么的区别?
前者是在字符串常量池和堆内存中都创建了一个"abc"字符串对象。后者是在字符串常量池中创建了一个"abc"字符串对象。
public class StringDemo2 { public static void main(String[] args) { String s1 = new String("hello"); String s2 = "hello"; System.out.println(s1 == s2); System.out.println(s1.equals(s2)); } }运行结果:
分析:==:比较引用类型比较的是地址值是否相同。equals:比较引用类型默认也是比较地址值是否相同,而String类重写了equals()方法,比较的是内容是否相同。
面试题3:
public class StringDemo4 { public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; String s3 = "helloworld"; System.out.println(s3 == s1 + s2); System.out.println(s3.equals((s1 + s2))); System.out.println(s3 == "hello" + "world"); System.out.println(s3.equals("hello" + "world")); } }运行结果:
分析原因:为什么第一条输出语句是false,而第三条输出语句是true呢?
字符串如果是变量相加,先开空间,再拼接,所以第一条输出语句的结果是false;而字符串如果是常量相加,是先加,然后在常量池找,如果有就直接返回,否则,就创建,所以第三条输出语句的结果是true。
boolean equals(Object obj):比较字符串的内容是否相同,区分大小写
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
boolean contains(String str):判断大字符串中是否包含小字符串
boolean startsWith(String str):判断字符串是否以某个指定的字符串开头
boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾
boolean isEmpty():判断字符串是否为空。
public class StringDemo { public static void main(String[] args) { // 创建字符串对象 String s1 = "helloworld"; String s2 = "helloworld"; String s3 = "HelloWorld"; // boolean equals(Object obj):比较字符串的内容是否相同,区分大小写 System.out.println("equals:" + s1.equals(s2)); System.out.println("equals:" + s1.equals(s3)); System.out.println("-----------------------"); // boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写 System.out.println("equals:" + s1.equalsIgnoreCase(s2)); System.out.println("equals:" + s1.equalsIgnoreCase(s3)); System.out.println("-----------------------"); // boolean contains(String str):判断大字符串中是否包含小字符串 System.out.println("contains:" + s1.contains("hello")); System.out.println("contains:" + s1.contains("hw")); System.out.println("-----------------------"); // boolean startsWith(String str):判断字符串是否以某个指定的字符串开头 System.out.println("startsWith:" + s1.startsWith("h")); System.out.println("startsWith:" + s1.startsWith("hello")); System.out.println("startsWith:" + s1.startsWith("world")); System.out.println("-----------------------"); // 练习:boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾这个自己玩 // boolean isEmpty():判断字符串是否为空。 System.out.println("isEmpty:" + s1.isEmpty()); String s4 = ""; String s5 = null; System.out.println("isEmpty:" + s4.isEmpty()); // NullPointerException // s5对象都不存在,所以不能调用方法,空指针异常 System.out.println("isEmpty:" + s5.isEmpty()); } }运行结果:
int length():获取字符串的长度。
char charAt(int index):获取指定索引位置的字符。
int indexOf(int ch): 返回指定字符在此字符串中第一次出现处的索引。为什么这里是int类型,而不是char类型?原因是:'a'和97都可以代表'a',如果定为char类型,只能赋值为'a',如果定为int类型,'a'和97都可以。
int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引。
int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引。
int indexOf(String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引。
String substring(int start):从指定位置开始截取字符串,默认到末尾。
String substring(int start,int end):从指定位置开始到指定位置结束截取字符串。包含上边界,不包含下边界。[ )
public class StringDemo { public static void main(String[] args) { //定义一个字符串 String s = "helloworld"; //int length():获取字符串长度。 System.out.println("s.length():"+s.length()); System.out.println("----------------"); //char charAt(int index):获取指定索引位置的字符 System.out.println("charAt:"+s.charAt(9)); System.out.println("----------------"); //int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引 System.out.println("indexOf:"+s.indexOf('l')); System.out.println("----------------"); //int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引。 System.out.println("indexOf:"+s.indexOf("owo")); System.out.println("----------------"); //int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引。 System.out.println("indexOf:"+s.indexOf('l',4)); System.out.println("indexOf:" + s.indexOf('k', 4)); System.out.println("----------------"); //int indexOf(String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引。 //String substring(int start):从指定位置开始截取字符串,默认到末尾。 System.out.println("substring:"+s.substring(5)); System.out.println("substring:"+s.substring(0)); System.out.println("----------------"); //String substring(int start,int end):从指定位置开始到指定位置结束截取字符串。 //包含上边界,不包含下边界 System.out.println("substring:"+s.substring(3, 8)); System.out.println("substring:"+s.substring(0,s.length())); } }运行结果:
练习1:遍历获取字符串中的每一个字符(其实也可以先将字符串转为字符数组,然后遍历,这个在转换功能里将)
/* * 需求:遍历获取字符串中的每一个字符 * * 分析: * A:如何能够拿到每一个字符呢? * char charAt(int index) * B:我怎么知道字符到底有多少个呢? * int length() */ public class StringTest { public static void main(String[] args) { String s = "helloworld"; for(int x = 0;x < s.length();x++){ System.out.print(s.charAt(x)); } } }运行结果:
练习2:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
/* * 需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符) * 举例: * "Hello123World" * 结果: * 大写字符:2个 * 小写字符:8个 * 数字字符:3个 * * 分析: * A:定义一个字符串和三个统计变量 * String s = "Hello123World" * bigCount=0 * smallCount=0 * numberCount=0 * B:遍历字符串,得到每一个字符。 * length()和charAt()结合 * C:判断该字符到底是属于那种类型的 * char ch = s.charAt(x); * if(ch>='0' && ch<='9') numberCount++ * if(ch>='a' && ch<='z') smallCount++ * if(ch>='A' && ch<='Z') bigCount++ */ public class StringTest2 { public static void main(String[] args) { String s = "Hello123World"; int bigCount = 0; int smallCount = 0; int numberCount = 0; for (int x = 0; x < s.length(); x++) { char ch = s.charAt(x); if (ch >= '0' && ch <= '9') { numberCount++; } else if (ch >= 'a' && ch <= 'z') { smallCount++; } else if (ch >= 'A' && ch <= 'Z') { bigCount++; } } System.out.println(numberCount); System.out.println(bigCount); System.out.println(smallCount); } }运行结果:
byte[] getBytes():把字符串转换为字节数组。
char[] toCharArray():把字符串转换为字符数组。
static String valueOf(char[] chs):把字符数组转成字符串。
static String valueOf(int i):把int类型的数据转成字符串。注意:String类的valueOf方法可以把任意类型的数据转成字符串。
String toLowerCase():把字符串转成小写。
String toUpperCase():把字符串转成大写。
String concat(String str):把字符串拼接。
public class StringDemo { public static void main(String[] args) { // 顶一个字符串对象 String s = "JavaSE"; // byte[] getBytes():把字符串转换成字节数组 byte[] bys = s.getBytes(); for (int x = 0; x < bys.length; x++) { System.out.print(bys[x] + " "); } System.out.println(); System.out.println("--------------"); // char[] toCharArray():把字符串转换成字符数组 char[] chs = s.toCharArray(); for (int x = 0; x < chs.length; x++) { System.out.print(chs[x] + " "); } System.out.println(); System.out.println("--------------"); // static String valueOf(char[] chs):把字符数组转成字符串 String ss = String.valueOf(chs); System.out.println(ss); System.out.println(); System.out.println("--------------"); // static String valueOf(int[] i):把int类型数据转换成字符串 int i = 100; String sss = String.valueOf(i); System.out.println(sss); System.out.println("--------------"); // String toLowerCase():把字符串转成小写。 System.out.println("toLowerCase:" + s.toLowerCase()); System.out.println("s:" + s); System.out.println("--------------"); // String toUpperCase():把字符串转成大写 System.out.println("toUpperCase:" + s.toUpperCase()); System.out.println("--------------"); // String concat(String str):把字符串拼接 String s1 = "hello"; String s2 = "world"; String s3 = s1 + s2; String s4 = s1.concat(s2); System.out.println("s3:"+s3); System.out.println("s4:"+s4); } }运行结果:
练习:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
思路:定义一个字符串,先截取该字符串的第一个字母,然后再截取其他部分。将截取的第一个字母转为大写,截取的其他部分转为小写。最后将两部分拼接起来。
public class StringTest { public static void main(String[] args) { //定义一个字符串 String s = "helloWORLD"; //先获取第一个字符 String s1 = s.substring(0,1); String s2 = s.substring(1); String s3 = s1.toUpperCase(); String s4 = s2.toLowerCase(); String s5 = s3.concat(s4); System.out.println(s5); //优化后的代码 //链式编程 String result = s.substring(0,1).toUpperCase().concat(s.substring(1).toLowerCase()); System.out.println(result); } }运行结果:
替换功能:
String replace(char old,char new)
String replace(String old,String new)
去除字符串两端空格:
String trim()
按字典顺序比较两个字符串:
int compareTo(String str)
int compareToIgnoreCase(String str)
public class StringDemo { public static void main(String[] args) { //替换功能 String s1 = "helloworld"; String s2 = s1.replace('l','k'); String s3 = s1.replace("owo","ak47"); System.out.println("s1:"+s1); System.out.println("s2:"+s2); System.out.println("s3:"+s3); //去掉字符串两端空格 String s4 = " hello world "; String s5 = s4.trim(); System.out.println("s4:"+s4+"---"); System.out.println("s5:"+s5+"---"); //按字典顺序比较两个字符串 String s6 = "hello"; String s7 = "hello"; String s8 = "abc"; String s9 = "xyz"; System.out.println(s6.compareTo(s7)); System.out.println(s6.compareTo(s8)); System.out.println(s6.compareTo(s9)); } }运行结果:
练习1:把数组中的数据按照指定格式拼接成一个字符串。例如,将int[] arr = {1,2,3};按拼接成一个“[1 2 3]”字符串
/* * 需求:把数组中的数据按照指定个格式拼接成一个字符串 * 举例: * int[] arr = {1,2,3}; * 输出结果: * "[1, 2, 3]" * 分析: * A:定义一个字符串对象,只不过内容为空 * B:先把字符串拼接一个"[" * C:遍历int数组,得到每一个元素 * D:先判断该元素是否为最后一个 * 是:就直接拼接元素和"]" * 不是:就拼接元素和逗号以及空格 * E:输出拼接后的字符串 */ public class StringTest2 { public static void main(String[] args) { int[] arr = {1,2,3}; System.out.println(arrayToString(arr)); } //用功能实现 public static String arrayToString(int[] arr){ String s = ""; s+="{"; for(int x = 0;x < arr.length;x++){ if(x == arr.length-1){ s+=arr[x]; s+="}"; } else{ s+=arr[x]; s+=" "; } } return s; } }运行结果:
练习2:字符串反转。例如,键盘录入“abc”,输出“cba”。
/* * 字符串反转 * 举例:键盘录入”abc” * 输出结果:”cba” * * 分析: * A:键盘录入一个字符串 * B:定义一个新字符串 * C:倒着遍历字符串,得到每一个字符 * a:length()和charAt()结合 * b:把字符串转成字符数组 * D:用新字符串把每一个字符拼接起来 * E:输出新串 */ import java.util.Scanner; public class StringTest3 { public static void main(String[] args) { // 创建对象 Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串:"); String s = sc.nextLine(); String result = reverseString(s); System.out.println(result); String result2 = reverseString2(s); System.out.println(result2); } public static String reverseString(String s) { String str = ""; //数组遍历 for (int x = s.length() - 1; x >= 0; x--) { str += s.charAt(x); } return str; } public static String reverseString2(String s) { String str = ""; // 把字符串转成字符数组 char[] chs = s.toCharArray(); //数组遍历 for (int x = chs.length - 1; x >= 0; x--) { str += chs[x]; } return str; } }运行结果:
练习3:统计大串中小串出现的次数。例如,统计字符串"woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun"中“java”出现的次数。
/* * 统计大串中小串出现的次数 * 举例: * 在字符串"woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun" * 结果: * java出现了5次 * * 分析: * 前提:是已经知道了大串和小串。 * * A:定义一个统计变量,初始化值是0; * B:在大串中查找一次小串第一次出现的位置 * a:索引是-1,说明不存在了,返回统计变量 * b:索引不是-1,说明存在,统计变量++ * C:把刚才的索引+小串的长度作为开始位置截取上一次的大串,返回一个新的字符串,并把字符串的值重新赋值给大串 * D:返回B */ public class StringTest4 { public static void main(String[] args) { //定义大串 String maxString = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun"; //定义小串 String minString = "java"; int count = getCount(maxString,minString); System.out.println(count); } public static int getCount(String maxString,String minString){ int count = 0;//定义一个统计变量 while(true){ int index = maxString.indexOf(minString);//先在大串中查找一次小串第一次出现的位置 if(index==-1){//判断 break; } else{ count++; } maxString = maxString.substring(index+minString.length()); } return count; } }运行结果:
代码优化:
public class StringTest5 { public static void main(String[] args) { String maxString = "woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun"; String minString = "java"; int count = getCount(maxString, minString); System.out.println(count); } public static int getCount(String maxString, String minString) { int count = 0; int index = 0; while ((index = maxString.indexOf(minString)) != -1) { count++; maxString = maxString.substring(index + minString.length()); } return count; } }运行结果: