面向对象讲完之后就是API,也就是我们现在要说的这些,这里面我们会接触大量的方法,只有多看多用,你才能记住,下面我们就来说一下常用的类。
Objec是Java中的顶级父类,Java中所有的类都默认直接或者间接的继承object。Objec是Java中唯一没有父类的类,任何一个类的对象都可以用Object对象接住。
构造方法中提供的所有构造方法默认是public修饰的。
Object class 中只提供了这么一个无参的构造函数。
克隆对象。克隆完成之后会产生一个新的对象,这个新对象和原对象的地址不同但是属性值是一样的。
一个对象要想被克隆,那么这个对象对应的类必须实现Cloneable接口,Cloneable接口中没有任何的方法和属性,仅仅用于标识这个类产生的对象可以被克隆。
public class T1 implements Cloneable {
int i;
public static void main(String[] args) throws CloneNotSupportedException {
T1 t = new T1();
t.i = 5;
T1 t1 = (T1) t.clone();
System.out.println(t);
System.out.println(t1);
}
}
判断两个对象是否一致。默认比较的是对象的地址,即使用的是==运算符,在开发中要求能够手动重写。Eclipse中右键Sourec中有自动生成。
书写步骤:
1.判断地址是否一样,即直接使用==运算符。
2.判断对象是否为空。
3.判断对象的创建类型是否一致。
4.判断属性值是否一致。判断之前要将对象强转为顶级父类。判断属性值的时候注意String类型的判断。
Public boolean equals(Object obj){
if (this == obj) //1.判断地址是否一致
return true;
if (obj == null) //2.判断参数是否为空
return false;
if (getClass() != obj.getClass()) //3.判断类型是否一致
return false;
Person other = (Person) obj; //4.强制转换类别
if (age != other.age) //5.判断属性是否一致
return false;
if (gender != other.gender)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
通知gc回收垃圾对象,但是垃圾回收器不一定执行。即使gc开始运行,也只回收当前对象而不回收其他对象。
相似的:System.gc();通知gc回收对象,不限制范围。
个人理解:这个方法实在是很尴尬的一个方法,不能发号施令,只能干吆喝,干不干是别人的事。这就相当于街头小贩了,只吆喝,管不了你买不买。
获取对象的实际类型(创建类型)。
返回对象的哈希码值的十进制。哈希码是一串32位的二进制数据,由于出现相同的数值的概率非常低,所以可以认为是唯一的。(不建议手动重写)
重写hashCode的时候,当equals值为true的时候,哈希码必须一致。但是哈希码一致equals不一定为true。
native关键字修饰的是本地方法,底层是用c语言写的。
返回对象的字符串形式,默认返回对象的地址。当打印对象的时候默认是调用了这个对象的toString方法。一般会重写。
==和equals有什么区别?
当是基本类型的时候,==判断的是实际数据;对于引用类型而言==判断的是地址。
equals只能作用于引用类型,默认比较的是两个对象的地址;当重写来equals的时候,按照重写之后的要求进行比较。
String class 就是字符串类,我看了源码,底层就是使用char数组存储数据的。
1.String是一个最终类,代表字符串的一个类,所有的字符串都是String的对象。
2.字符串是一个常量;字符串可以被共享。
3.字符串是存在方法区。
4.注意不同的方式创建的对象的个数。有几个对象,就看内存中有几个存储的是地址。
String s = “abc”; //产生了1对象
String s = new String(“abc”); //产生了2个对象
String s = “a”; s += “b”; //产生了5个对象
String s = “a”; //产生了1个对象
s = new StringBuilder(“a”).append(“b”).toString(); //这个过程产生了4对象
String s = “a”; s += “b”; //1个a,1个b,2个对象。
String s = “a”; //
s = new StringBuilder(“a”).append(“b”).toString();
//3个对象:StringBuilder1个,append拼接产生1个,toString产生1个。
s = new String(“ab”);//最终只存活了4个对象,StringBuilder产生的对象会被解析。
// 100个字符串组成的字符数组
String[] arr = new String[100];
// + 进行拼接
String s = “”; // 1
for(String str : arr){
s += str; //s = new StringBuilder(s).append(str).toString(); //300
}
// StringBuilder
StringBuilder sb = new StringBuilder(); // 1
for(String str : arr){
sb.append(str); // 100
}
String s = sb.toString(); // 1
操作字符串的一个类,不保证同步,是一个线程不安全的类。效率高一些。
在进行字符串拼接的时候JVM会在底层调用StringBuilder的append方法,进行拼接。
如果拼接多个字符串,建议使用StringBuilder;如果拼接少量字符串,可以使用+。
构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
构造一个不带任何字符,容量有参数确定的字符串生成器。
构造一个字符串生成器,并初始化为指定的字符串内容。
将参数的字符串形式追加到此序列。
返回当前容量。
StringBuffer 和StringBuilder中的方法在使用上完全一致的。
StringBuffer也是操作字符串的一个类,是一个线程安全的类。
字段摘要里面介绍的变量都是常量。
创建一个字符串对象。
String s = null; //没有对象产生。
String s = “ ”; //有1个对象,存储在常量池中,值为空即null。
String s = new String(); //堆内存中存储一个对象,值为null。
String s = new String(“ ”); //2个对象一个堆内存中,一个方法区中。
将字节数组按照系统默认编码转化为字符串。
byte[] bs = {97,98,100};
String s = new String(bs);
Byte[] bs = “汉字”.getByte(); //转化为字节数组。
String s = new String(bs);
将字符串按照指定的编码编译。
将字节数组按照指定的编码ch,从下标index开始,转化size个。
将字符数组中的元素拼接成一个字符串。
char[] cs = { 'a', 'd', 'e', 'g', 'b', 'm', 'o' };
String s = new String(cs);
表示从字符数组的指定下标i开始将指定的个数k拼成字符串。
String s = new String(cs, 2, 4);
分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。该字符串缓冲区的内容已被复制,后续对它的修改不会影响新创建的字符串。
分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。该字符串缓冲区的内容已被复制,后续对它的修改不会影响新创建的字符串。
表示获取这个字符串指定下标index位置上的字符。
String s = “jbksedfgew”;
System.out.println(s.charAt(4));
获取字符串的长度。
注意数组中的length是一个属性,字符串的length();是个方法。
System.out.println(s.length());
1.统计字符串中字母和数字的个数
输入一个字符串,分别统计之歌字符串中字母和数字的个数。
Scanner s = new Scanner(System.in);
String str = s.nextLine();
s.close();
int letterNo=0,numberNo=0;
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)>='a'&&str.charAt(i)<='z'||str.charAt(i)>='A'&&str.charAt(i)<='Z'){
letterNo++;
}else if(str.charAt(i)>='0'&&str.charAt(i)<='9'){
numberNo++;
}
}
System.out.println("字母为"+letterNo+"个,数字为"+numberNo+"个");
2.获取字符串中所有数字
输入一个字符串,获取之歌字符串中的所有数字并排序。
Scanner s=new Scanner(System.in);
String str = s.next();
s.close();
int count = 0;
char[] c1 = new char[str.length()];
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c>='0'&&c<='9'){
c1[count]=c;
count++;
}
}
c1=Arrays.copyOf(c1, count);
Arrays.sort(c1);
System.out.println(new String(c1));
3.将数字字符串求和
输入一个串由数字组成的字符串,将这串数字求和。
Scanner s = new Scanner(System.in);
String str =s.next();
s.close();
int sum = 0;
for (int i = 0; i < str.length(); i++) {
sum+=(str.charAt(i)-'0');
}
System.out.println(sum);
比较两个字符串的大小。根据返回值的正负来确定大小
按照升序规则比较两个字符串
1. 将两个字符串转化为两个字符数组。
2. 对象字符串对应的字符数组的对应位置的字符 -/减 参数字符串对应的数组对应位置的字符。
3. 如果差不为0,那么直接返回。 如果差为0,则下一位对应的字符继续相减。
4. 如果对应位置的字符全部减完,依然没有返回的话,那么就会返回对象字符串-参数字符串的长度之差。如果返回的是一个正数,说明对象字符串要大一些,如果返回的是一个负数,说明参数字符串要大一些。
System.out.println(str.compareTo("dhnalgola"));
System.out.println(str.compareToIgnoreCase("DHNALGOLA"));
不区分大小写比较两个字符串的大小。
将参数字符串拼接到对象字符串的末尾,返回一个新的字符串而不改变原串。
//将参数字符串拼接对象字符串的尾部---产生一个新串而不改变原串
/*
* 1. 将两个字符串转化为字符数组
* c1, c2
* 2. 将两个字符数组进行合并
* char[] cs = new char[c1.length + c2.length]; //创建一个新数组。
* System.arraycopy(c1,0,cs,0,c1.length); //将两个数组放入新数组
* System.arraycopy(c2,0,cs,c1.length,c2.length);
* 3. 将合并后的字符数组转化为字符串返回
* return new String(cs);
*/
System.out.println(str.concat("abc"));
System.out.println(str);
注意:在String中提供了一系列的操作而不改变的原串的方法。
判断是否包含指定的子串
判断字符串是否以指定字符结尾。经常用于筛选。
String中已经对equals做了重写。判断两个字符串是否相等,判断的是实际值。
String str = new String("abcdefghijkmn");
// 判断是否包含指定的子串
System.out.println(str.contains("dee"));
// 判断是否是指定的结尾---筛选
// .docx
System.out.println(str.endsWith("mn"));
// 判断是否为指定的开头
System.out.println(str.startsWith("a"));
// 对equals方法做过了重写,判断的是两个字符串的实际值是否一样
// 将两个字符串转化为字符数组,然后按位比较
System.out.println(str.equals(new String("ABCDEFGHIJKMN")));
// 适用于验证码,不区分大小写
System.out.println(str.equalsIgnoreCase(new String("ABCDEFGHIJKMN")));
忽略大小写判断是否相等。
将字符串转化为字节数组,如果不指定编码,会按照默认的系统平台码转化。
将字符串按照指定编码转化为字节数组。
之前说过一次编码,这里简单再说一下。
编码:按照某种规则将字符映射成字节,记录这种规则的形式,就是编码表。
ASCII,0-127,不完全的码表。
ISO-8859-1,西欧码表,一个字符一个字节。
gb2312,一个字符2个字节,包含了常见的基本简体汉字以及部分的繁体汉字,gbk
Unicode编码体系,utf-8,一个字符3个字节,常见语言的常见字符。
后续的所有码表默认兼容西欧码表:只要是英文,永远是一个字符对应一个字节。
String str = "中文";
// 表示将字符串转化为字节数组
// 如果没有指定编码,会默认采用系统平台码
byte[] bs = str.getBytes("utf-8");
System.out.println(bs.length);
System.out.println(new String(bs, 0, 3, "UTF-8"));
for (byte b : bs) {
System.out.println(b);
}
byte[] bs = {12,55,120,127,15};
// 将字节数组转化为字符串
// 表示从字节数组的下标为1的位置开始转化,转化2个字节
System.out.println(new String(bs,1,2));
截取字符串指定字节
输入一个字符串和一个数字,数字表示字节个数,然后按照指定的字节个数来截取字符串
中文english国 5 -> 中文e 6 -> 中文en 2 -> 中 3 -> 中 12-> 中文english?
方法一:
public static void printStr2(String str,int number){
//判断字符串是否为空
if(str==null){
return;
}
//判断字节个数是否是非负数
if(number<0){
return;
}
//先将所有的字符看成中文
int index = number/2;
//按照这个新的长度从原字符串身上截取
String newstr = str.substring(0,index);
while(newstr.getBytes().length!=number){
//如果少来就多添加一个字符
if(newstr.getBytes().length0,index);
}else{
index--;
newstr = str.substring(0,index);
break;
}
}
System.out.println(str.substring(0,index));
}
方法二:
public static void printStr1(String str,int number){
//判断字符串是否为空
if(str==null){
return;
}
//判断字节个数是否是非负数
if(number<0){
return;
}
//获取字符串对应的字节数组
byte[] b = str.getBytes();
//创建一个新的字节数组用来放截取之后的字节组数
byte[] newb = Arrays.copyOf(b, number);
//将新数组转化成一个字符串
String st = new String(newb);
//获取这个字符串最后一个字符
char c = st.charAt(st.length()-1);
//获取原字符串对应位置上的字符
char oldc = str.charAt(st.length()-1);
System.out.println(c == oldc ? st : new String(newb, 0, newb.length - 1));
String中的hashCode方法做过了重写,同一个字符串在任何情况下的哈希码都是一样的。
获取指定字符c在字符串中的第一次出现的位置,如果找不到该字符会返回一个-1。
表示从指定的下标i开始向后寻找该字符c出现的位置。
输出字符在字符串中的出现的位置
输入一个字符串和一个字符,输出这个字符出现的所有位置。
public static void all(String str, String sub) {
// 判断str是否为null
if (str == null) {
return;
}
// 记录位置
int index = 0;
while (index < str.length()) {
// 获取指定字符第一次出现的位置
index = str.indexOf(sub, index);
if (index != -1) {
System.out.println(index);
index++;
} else {
return;
}
}
判断字符串长度是否为0.
表示最后一次出现的位置。
从指定下标开始向前寻找最后一次出现的位置。
返回一个新字符串,替换。
Java中的范围包前不包后,包左不包右,包小不包大。
判断是否指定参数作为开头。作为筛选使用。
从指定下标开始截取。
从指定位置开始截取,截取到指定位置的前一位。
将字符串转化为字符数组。
转化为小写。
1.现将字符串化为字符数组。
2.便利数组,判断每一位是否是一个大写字母。
3.如果是一个大写字母,这以为加上32然后在强转回char类型,再赋值给原位置。
4.将字符数组转化为字符串。
转为大写。
返回本身。
去掉字符串前后的空白符。
返回参数的对应字符串形式。
// valueOf是一个静态方法---表示将参数转化为一个字符串
// 如果传入的是一个对象,则会调用这个对象的toString方法
System.out.println(String.valueOf(new Object()));
System.out.println(String.valueOf(new int[] { 2, 5, 1, 7, 0 }));
// 如果传入的是字符数组,则会转化为字符串显示
System.out.println(String.valueOf(new char[] { 'a', 'b', 'c' }));
System.out.println(new char[] { 'a', 'd', 'g' });
在java中正则表达式所对应的类是pattern class,所在的包是Regex。
本质上使用与指定匹配或者筛选规则的一系列表达式。
每个字符在匹配的时候只能跟一个数量词。
用于过滤筛选。
a、b或c。[]括号中的字母可以按照自己的使用要求任意改换。
//字符串由三个字母组成, abc/def/opq
System.out.println(str.matches("[cab][def][opq]"));
a 到z或A到Z,两头的字母包含在内。[]括号中的内容可以按照自己的使用要求任意替换成一段连续的字符。
// 判断字符串是否是由一个字母组成
System.out.println(str.matches("[a-zA-Z]"));
任何字符,除了a、b或c。[]括号中的字母可以按照自己的使用要求任意改换。
// 字符串由一个字符组成,字符不是a/d/h/l/p
System.out.println(str.matches("[^adhlp]"));
表示任意字符。
// 匹配字母a开头的由两个字符组成的字符串
// . 表示任意字符
System.out.println(str.startsWith("a") && str.length() == 2);
System.out.println(str.matches("a."));
表示匹配点。
// 匹配 "."
System.out.println(str.matches("\\."));
匹配反斜杠。
// 匹配 \
// "\\\\ " -> "\\" -> \
// 路径名
System.out.println(str.matches("\\\\"));
表示所有数字。
// 任意一个数字
System.out.println(str.matches("[0-9]"));
System.out.println(str.matches("\\d"));
表示非数字。
表示空白符。
表示非空白。
表示单词字符。
非单词字符。
表示至少出现一次。>=1。
// 匹配字符a开头的至少由两个字符组成的字符串
// System.out.println(str.startsWith("a") && str.length() >= 2);
// + 表示至少出现一次
// "a+" 至少出现1个a
System.out.println(str.matches("a.+"));
表示至多出现一次。<=1。
// 匹配字符a开头的至多由2个字符组成的字符串
// ?表示至多一次
System.out.println(str.matches("a.?"));
表示可有可无,有的话不限制次数。>=0。
// 匹配字符串"ab"/"abc"/ abcc
// * 表示可有可无 ---如果有的话,不限制次数
System.out.println(str.matches("abc*"));
表示有n个字符组成。==n。
// 匹配由5个字符组成的字符串
System.out.println(str.length() == 5);
// {n} 表示恰好由n个字符组成
System.out.println(str.matches(".{5}"));
至少有n个组成。>=n。
// 匹配至少由5个字符a组成的字符串
// {n,} 至少由n个组成
// + -> {1,}
System.out.println(str.matches("a{5,}"));
数量在n到m之间。
// 匹配由8-12个字符组成的字符串
System.out.println(str.matches(".{8,12}"));
1.每个字符至多只能跟一个数量词。
2.在[]内一切数量词失效。
练习:
1.匹配小数。
输入一个字符串,判断这个字符串是否是一个小数。
package cn.tedu.regex;
import java.util.Scanner;
public class PatternExer1 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str = s.nextLine();
s.close();
// 3.21 10.53
System.out.println(str.trim().matches("0\\.\\d+|[1-9]\\d+\\.\\d+"));
}
}
2.匹配密码
长度8-12位,至少由字母数字空格至少有两种组成。
public class PatternExer5 {
public static void main(String[] args) {
String password = "";
System.out.println(checkPwd(password));
}
private static boolean checkPwd(String password) {
// 判断密码是否为空
if (password == null) {
return false;
}
// 判断密码的位数是否符合
if (!password.matches(".{8,12}")) {
return false;
}
// 记录出现的字符的种类
int i = 0;
// 判断是否含有字母
if (password.matches(".*[a-zA-Z].*")) {
i++;
}
// 判断是否包含数字
if (password.matches(".*\\d.*")) {
i++;
}
// 判断是否有符号
if (password.matches(".*\\W.*")) {
i++;
} else if (password.matches(".*_.*")) {
i++;
}
return i >= 2;
}
}
捕获组。
// (字符) --- 捕获组
System.out.println(str.matches(".*(abc).*"));
表示引用之前对应编号为n的捕获组。
捕获组的编号是从“(”第一次出现的位置开始计算的,java会对捕获组进行自动的编号,编号从1开始。
// 匹配至少含有两个"abc"的字符串
// \\n 表示引用之前对应编号为n的捕获组---捕获组的编号是从1开始的
System.out.println(str.matches(".*(abc).*\\1.*"));
1.匹配邮箱(典型练习)
package cn.tedu.regex;
public class PatternExer4 {
public static void main(String[] args) {
String email = "[email protected]";
System.out.println(checkEmail(email));
}
private static boolean checkEmail(String email) {
return email == null ? false : email.matches("\\w+@[0-9A-Za-z]+(\\.com)|\\w+@[0-9A-Za-z]+(\\.com)?(\\.cn)");
}
}
是否匹配参数。
将一类东西替换。后一个参数想引用前一个参数的捕获组,改用 符。 这个符号,仅限于此方法使用。
// String str = "adag35bknl2nkld08aadb";
// 将数字替换为*
// System.out.println(str.replaceAll("\\d", "*"));
// 消除所有的数字
// System.out.println(str.replaceAll("\\d", ""));
String str = "Amy Tom Sam David Grace";
// Tom和David调换顺序
System.out.println(str.replaceAll("(.*)(Tom)(.*)(David)(.*)", "$1$4$3$2$5"));
1.统计每个字符出现的个数。
从控制台输入一个字符串,统计每个字符出现的次数。
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str = s.next();
s.close();
while (str.length() > 0) {
// 记录字符串的原始长度
int len = str.length();
// 获取这个字符串的首字母
char c = str.charAt(0);
// 判断数量词
if (c == '+' || c == '?' || c == '*') {
str = str.replaceAll("\\"+c + "", "");
}else
// 去除掉这个字符串中的这个字母
str = str.replaceAll(c + "", "");
System.out.println(c + ":" + (len - str.length()));
}
}
2.叠字换单字
我我我我我我爱爱爱爱学学学学学学学学学学学学编编编程程程程程程 -> 我爱学编程
package cn.tedu.regex;
public class PatternExer3 {
public static void main(String[] args) {
String str = "我我我我我我爱爱爱爱学学学学学学学学学学学学编编编程程程程程程";
System.out.println(str.replaceAll("(.)\\1+", "$1"));
//$表示对前一个参数捕获组的引用
}
}
将字符串的首个reges替换为newstr。
字符串碎片的平均长度。
String str = "aasdddfdg";
// 记录字符串的长度
int len = str.length();
// 记录碎片的个数
double i = 0;
while (str.length() > 0) {
// 去掉首个叠字
str = str.replaceFirst("(.)\\1*", "");
// 记录+1
i++;
}
System.out.println(len/i);
以参数regex作为切割符将字符串分开,切完之后,作为切割符的字符就被切除掉了。如果两个切割符相连,这两个切割符之间会切出一个空字符串(“”);如果切割符在末尾,直接切除。如果在开头,会切出一个空字符串(“”)。
String str = "3aga2dha48nsl9dfg0";
// 以数字作为切割符将字符串分开
// 切完之后,作为切割符的符号就没切除掉了
// 如果两个切割符相连,这两个切割符之间会切出一个 ""
// 如果切割符在末尾,则会直接切除
String[] arr = str.split("\\d");
System.out.println(Arrays.toString(arr));
Object和String类大部分常用的方法,都给大家罗列出来了,有个别不常用的可以查找API。