代表任意一个字符序列。 字符串。 值不可变。 线程就是安全。引用数据类型 null
public final class String extends Object implements Serializable, Comparable<String>, CharSequence
1.1 常用构造
String(byte[] bytes) String(byte[] bytes, Charset charset) String(byte[] bytes, String charsetName) String(byte[] bytes, int offset, int length) IO //解码 (解密) 将看不懂的字节数据转换成指定编码格式下的字符串。 //编码格式: UTF-8 GBK //UTF-8: 3 //GBK: 2
String(char[] value) String(char[] value, int offset, int count) //将指定字符数组里面数据转换成字符串
String(String original) String(StringBuffer buffer) String(StringBuilder builder)
解码
private static void demo1() { //String类常用构造 //1.创建String类对象 String str = "hello"; /*char[] chars = {98, 99, 100, 'a', '获', '1'}; String str1 = new String(chars, 0, 3); System.out.println(str1);*/ //byte[] bytes = {-100, 98, 97, 56, 48, 67}; byte[] bytes = "周杰伦".getBytes();//编码 utf-8 String str2 = new String(bytes, Charset.forName("GBK"));//解码----->手动解码 乱码的时候 才会解码 //解码 //将看不懂的字节内容转换成指定编码格式下的字符数据 //查看当前环境里面的默认编码格式----> Charset System.out.println(Charset.defaultCharset());//UTF-8 System.out.println(str2);//�ba80C //是否可以实现将字符串转换成字节数据? //将看的懂的字符串数据转换成看不懂的字节内容-----> 编码 // String name = "周杰伦"; // byte[] nameBytes = name.getBytes();//转换成默认编码格式下的字节数据 // System.out.println(Arrays.toString(nameBytes)); }
1.2 常用方法
0. 值不可变
为什么说String数据不可变?
public String(String original) { this.value = original.value; this.coder = original.coder; this.hash = original.hash; } private final byte[] value;//字符串数据不可变原因。
1. 与数组相关
将字符串转换成数组相关的数据。
byte[] getBytes() byte[] getBytes(Charset charset) byte[] getBytes(String charsetName) //将字符串转换成指定编码格式下的字节数组数据 编码
char[] toCharArray() //将指定的字符串的数据 转换成字符数组
String[] split(String regex) //根据指定的正则表达式要求分隔字符串 String[] split(String regex, int limit)
private static void demo4() { String s = "abcabaaa"; String[] as = s.split("a",-1); System.out.println(Arrays.toString(as)); //统计原字符串里面a出现的次数 3次 //split(str,limit); //假设最多分为: length个 //limit>0 limit<=length 限定数组里面元素个数 //limit>length 数组里面元素还是length个 //尽可能使用length limit<0 //limit=0 当数组里面最后的元素为空字符 直接省略 System.out.println("a出现的次数:"+(as.length-1)); } private static void demo3() { String string = "值不可变"; //byte[] bytes = string.getBytes();//转换成当前平台默认编码格式下的字节数据 UTF-8 //byte[] bytes = string.getBytes("gbk");//转换成指定默认编码格式下的字节数据 byte[] bytes = string.getBytes(Charset.forName("GBK"));//转换成指定默认编码格式下的字节数据 System.out.println(Charset.defaultCharset()); System.out.println(Arrays.toString(bytes)); System.out.println("--------------------------------"); char[] chars = string.toCharArray(); System.out.println(Arrays.toString(chars)); String str = "abcadad"; //使用a分隔字符串 String[] array = str.split("a"); System.out.println(Arrays.toString(array)); //为什么最后有一个分隔内容的时候,反而分出来的数据 少了一个? 空字符 //分隔使用的场景是什么? //用户注册---->持久化报存----->文件里面 //id-name-age-pass String userInfoStr = "1001-张三-30-1234"; String[] infoArray = userInfoStr.split("-"); //将字符串的数据转换成UserInfo对象信息 UserInfo userInfo = new UserInfo(); userInfo.setId(Integer.parseInt(infoArray[0])); userInfo.setName(infoArray[1]); userInfo.setPass(infoArray[3]); userInfo.setAge(Integer.parseInt(infoArray[2])); System.out.println(userInfo); String fileName = "美女.jpg"; //获得文件的扩展名 String[] split = fileName.split("\\.");//将这个.转义成一个普通的. \ System.out.println(Arrays.toString(split)); System.out.println(split[split.length - 1]); }
2. 提取字符串
获得字符串里面其中一部分数据
char charAt(int index); 获得指定索引的字符的数据 index>=0 index<length()-1
private static void demo5() { String str = "获得字符串里面的所有的字符个数"; //获得第3个字符内容 //char charAt(int index); System.out.println(str.length());//获得字符串里面的所有的字符个数 char c = str.charAt(2); System.out.println(c); //final byte[] value //遍历打印字符串里面所有字符 for (int index = 0; index < str.length(); index++) { System.out.println(str.charAt(index)); } }
String substring(int beginIndex) String substring(int beginIndex, int endIndex) //截取 从指定的索引开始 截取一部分数据
private static void demo6() { String str = "abcdefg"; String substring = str.substring(3);//从指定的索引开始进行截取 一直到最后 包含开始索引 System.out.println(substring); String substring1 = str.substring(0, 3);//包头不包尾 不包含结束的索引位置 System.out.println(substring1); //场景? String phone = "17767898907";//长度是固定的 String first = phone.substring(0, 4); String last = phone.substring(7); System.out.println(first + "****" + last); //给用户看的时候 //数据存储还是17767898907 }
String trim() //去除字符串左右2端空格
3. 字符串搜索
int indexOf(String str) int indexOf(String str, int fromIndex) //获得指定字符串第一次出现的索引位置 //没有找到指定的字符 返回值 -1 int lastIndexOf(String str) int lastIndexOf(String str, int fromIndex) //获得指定字符串最后一次出现的索引位置 //没有找到指定的字符 返回值 -1
private static void demo3() { String filePath = "D:\\demo\\a\\b\\a.jpg"; //获得文件名称 //String[] array = filePath.split("\\\\"); //System.out.println(array[array.length - 1]); //核心: 找最后一个\\出现的索引位置 String fileName = filePath.substring(filePath.lastIndexOf("\\")+1); System.out.println(fileName); } private static void demo2() { String str = "abaaacdabc"; //需求: 使用indexOf或者lastIndexOf 求指定字符串出现次数 //a int count = 0; int startIndex = 0; while (true) { int index = str.indexOf("a", startIndex); if (index == -1) { break; } count++; startIndex = index + 1; } System.out.println("a出现的次数:" + count); } private static void demo1() { String str = "abcdabc"; //获得字符a第一次出现的索引位置 //int index = str.indexOf("a"); int index = str.indexOf("a", 3);//从指定索引处 查询指定字符串第一次出现的索引位置 System.out.println(index); //获得字符a最后一次出现的索引位置 //int lastIndex = str.lastIndexOf("a"); int lastIndex = str.lastIndexOf("a", 3); System.out.println(lastIndex); }
4.字符串比较判断
boolean equals(Object anObject) 比较2个字符串数据是否相等 int compareTo(String anotherString) 0 正数 负数 boolean equalsIgnoreCase(String anotherString) //不区分大小写进行 比较 boolean contains(CharSequence s) //判断字符串那里面是否包含指定的字符串的数据 boolean isEmpty() // 判断字符串是否是空字符 boolean startsWith(String prefix) //判断字符串是否以指定数据开头 boolean endsWith(String suffix) //判断是否以指定的字符串结尾
5. 字符串替换
String replace(char oldChar, char newChar) String replace(CharSequence target, CharSequence replacement) String replaceAll(String regex, String replacement) // 替换所有满足正则语法要求的字符串数据 String replaceFirst(String regex, String replacement) // 替换第一个满足正则语法要求的字符串数据
6. 其它
String intern() static String join(CharSequence delimiter, CharSequence... elements) //对指定字符串进行大写或者小写转换 String toLowerCase() String toUpperCase() String.valueOf(); 将其他类型的数据转换成String
private static void demo4() { String str = "Abedf"; System.out.println(str.toUpperCase().toLowerCase()); String s = String.valueOf(100.123); System.out.println(s); //join() 连接 使用特定分隔符将多个字符序列连接在一起 //String join(CharSequence delimiter, CharSequence... elements) //delimiter: 分隔符 自定义 //可变参数 >=0 数组 //执行用户注册 Scanner input = new Scanner(System.in); System.out.println("请录入id:"); int id = input.nextInt(); System.out.println("请录入name:"); String name = input.next(); System.out.println("请录入age:"); String age = input.next(); System.out.println("请录入pass:"); String pass = input.next(); //1001-张三-30-1234 //String userInfoStr = id + "-" + name + "-" + age + "-" + pass; //id.concat("-").concat(name).concat("-") String userInfoStr = String.join("-", String.valueOf(id), name, age, pass); System.out.println(userInfoStr); }
1.3 正则表达式(了解)
读懂就可以。百度
正则表达式通常被用来检索(匹配/校验)、替换那些符合某个模式(规则)的文本。
String[] split(String regex); String replaceAll(String regex, String replacement) String replaceFirst(String regex, String replacement) boolean matches(String regex)
String regex = "a";
正则语法: String regex = "^([]{})([]{})([]{})([]{})([]{})$"; ^: 以***开头 []: 文本字符。 匹配[]里面的内容。[a|b] [abc] {}:限定[]里面文本数据出现的次数。 [a]{1,} (): 组。域。在java语言中\n 代表第n个域。 n是从1开始的。 \n在正则模式里面使用。 替换环境中: $n 代表的是第n个域里面的内容。 $:以***结尾
\: 转义符号。 \\. \\ *: 匹配文本数据出现0次或者多次。 +:匹配文本数据出现1次或者多次。 .: 匹配除“\n”之外的任何单个字符 [a-z] [A-Z] [0-9] \d \w[a-zA-Z0-9_]
1. 对密码/用户名校验
用户录入的用户名或者是密码是否能够满足需求
private static void regexDemo1() { //用户名规则: //首字母必须大写 只能是一个 //有3-5个小写字母组成 //_必须有1个下划线 //有2-5个数字 String username = "Jimmy_123"; //校验用户名是否满足规则(模式)。 String regex = "^([A-Z]{1})([a-z]{3,5})([_]{1})([0-9]{2,5})$"; regex = "^[A-Z][a-z]{3,5}_\\d{2,5}$"; //校验: Patten代表正则 可以校验正则的语法是否ok 正则表达式的编译表示。 //java.util.regex.Pattern /*Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(username); boolean flag = matcher.matches(); System.out.println(flag);*/ //判断一个文本数据是否满足正则模式的需求 System.out.println(username.matches(regex)); }
2. 手机号码
private static void regexDemo2() { String phoneStr = "15278681234"; //1.校验手机号码是否是合法的 String phoneRegex = "^1[3-9]\\d{9}$"; if (!phoneStr.matches(phoneRegex)) { System.out.println(phoneStr + "不合法"); return; } //2.隐藏手机号中间的4位数字为**** //String replaceAll(String regex, String replacement) //替换内容:是动态获得原字符串里面的一部分 这个时候必须使用 () String regex = "^(\\d{3})\\d{4}(\\d{4})$"; System.out.println(phoneStr.replaceAll(regex, "$1****$2")); //156****1234 }
3. 去重
private static void regexDemo5() { String str = "abaa乌克克克克克aacccc乌克克克克克兰兰兰兰"; //排序---->数组 //字符串可以转数组 char[] chars = str.toCharArray(); Arrays.sort(chars); str = new String(chars); System.out.println(str);//aaaaabccccddd乌乌克克克克克克克克克克兰兰兰兰 //String replaceAll(String regex, String replacement) //前提: 满足字符数据是连贯的 //使用一个唯一字符替换重复n次字符数据-----> 匹配一个字符出现>=1 //多次替换: 不允许使用 ^ $ String regex = "(.)\\1+"; System.out.println(str.replaceAll(regex, "$1"));//效率高 }
1.4StringBuffer/StringBuilder
与String一致。代表的是字符串。 值是可变的。 可变的字符序列。
这两个类里面的方法一模样、
只要是线程安全的类 完全可以作为成员变量使用 (并发里面没有问题)
线程不安全的类 绝对不能作为成员变量使用 作为局部
值是否可变 | 线程安全/同步 | 性能 | 内存(拼接) | |
String | 不 | 安全 | 一般 | 浪费内存 |
StringBuffer | 可变 | 安全(synchronized) | 最慢 | 只有1个对象 |
StringBuilder(拼接 局部变量) | 可变 | 不安全 | 最快 | 只有1个对象 |
public static void main(String[] args) { //可变的字符序列 //1.创建StringBuilder对象 StringBuilder builder = new StringBuilder("hello"); //常用的功能方法 builder.append("abc"); //builder.insert(0,"abc"); //删除第一个l //builder.deleteCharAt(builder.indexOf("l"));// 删除指定索引的字符数据 //builder.delete(0,3); 删除指定索引范围内数据 //builder.replace(0,3,"abc"); //builder.reverse();//翻转字符串 System.out.println(builder); //StringBuffer buffer = new StringBuffer(); }
1.5课堂练习
1.编码,解码
public class StringDemo { public static void main(String[] args) { damo1(); } private static void damo1() { //String类常用构造 String(char[] value) 将指定字符数组里面的数据转换成字符串 char[] chars = {98,99,100,'a','b','或'}; String str1 = new String(chars); System.out.println(str1); //bcdab或 String str2 = new String(chars,0,3); //将一部分数组内容转化成字符串 System.out.println(str2); //bcd //String类常用构造 String(byte[] bytes) 将看不懂的字节数据转换成指定编码格式下的字符串。即:解码 (解密) byte[] bytes = {-100,98,78,56,48,67}; String str3 = new String(bytes); System.out.println(str3); //�bN80C 第一个在Utf-8找不到 System.out.println(Charset.defaultCharset()); //Utf-8 查看当前环境里的默认编码格式 Charset,是抽象类 //将看的懂得字符串数据转换成看不懂的字节内容,即编码 String name = "周杰伦"; byte[] nameBytes = name.getBytes(); System.out.println(nameBytes); // [B@3ac3fd8b System.out.println(Arrays.toString(nameBytes)); //[-27, -111, -88, -26, -99, -80, -28, -68, -90] byte[] bytes1 = "周杰伦".getBytes(); //编码 Utf-8下进行 System.out.println(bytes1); //[B@5594a1b5 String str4 = new String(bytes1); //解码 Utf-8下进行 System.out.println(bytes1); //[B@5594a1b5 String str5 = new String(bytes1,0,4); //从第一个字节开始,将4个字节转成字符串 System.out.println(str5); //周� String str6 = new String(bytes,Charset.forName("GBK")); //编码在utf-8下进行,解码在GBK下进行,故解码不是自己想要的数据 System.out.println(str6); //渂N80C GBK两个字节一个汉字 utf-83个字节一个汉字 } }
2.String值不可变
public class StringDemo { public static void main(String[] args) { damo2(); } private static void damo2() { //String值不可变 String str = "hello"; //数据存在常量池 String s = new String("abc"); //将字符串转数据 System.out.println(s); //abc s.concat(",world"); //拼接 在末尾追加指定字符串数据 System.out.println(s); //abc 原因:String值不可变 String s1 = s.concat(",world"); System.out.println(s1); //abc,world } }
3.String常用方法:与数组相关的
/*(1)将字符串转换成指定编码格式下的字节数组数据 编码 byte[] getBytes() byte[] getBytes(Charset charset) byte[] getBytes(String charsetName)*/ /*(2)将指定的字符串的数据 转换成字符数组 char[] toCharArray() */ /*(3)根据指定的正则表达式要求分隔字符串 String[] split(String regex) String[] split(String regex, int limit)*/ public class StringDemo { public static void main(String[] args) { damo3(); } private static void damo3() { String string = "可以"; byte[] bytes = string.getBytes(); //转换成当前平台默认编码格式下的字节数据 System.out.println(bytes); //[B@3ac3fd8b char[] chars = string.toCharArray(); System.out.println(Arrays.toString(chars)); //[可, 以] String str = "abcada"; //使用a分隔 String[] array = str.split("a"); System.out.println(Arrays.toString(array)); //[, bc, d] //分隔使用的场景是什么? 用户注册---->持久化报存----->文件里面 id-name-age-pass String userInfoStr = "1001-张三-30-1234"; String[] infoArray = userInfoStr.split("-"); //将字符串的数据转换成UserInfo对象信息 UserInfo userInfo = new UserInfo(); userInfo.setId(Integer.parseInt(infoArray[0])); //Id是Integer类型,String要转Integer userInfo.setName(infoArray[1]); userInfo.setPass(infoArray[3]); userInfo.setAge(Integer.parseInt(infoArray[2])); String fileName = "美女.jpg"; //获得文件的扩展名 String[] split = fileName.split("\\."); //将这个.转义成一个普通的.(转义是\,但java语言里不存在一个\,而是\\表示一个\) System.out.println(Arrays.toString(split)); System.out.println(split[split.length - 1]); } }
4.String常用方法:与数组相关的
/*(1)将字符串转换成指定编码格式下的字节数组数据 编码 byte[] getBytes() byte[] getBytes(Charset charset) byte[] getBytes(String charsetName)*/ /*(2)将指定的字符串的数据 转换成字符数组 char[] toCharArray() */ /*(3)根据指定的正则表达式要求分隔字符串 String[] split(String regex) String[] split(String regex, int limit)*/ public class StringDemo { public static void main(String[] args) { damo4(); } private static void damo4() { String s = "abcabaaa12"; String[] as = s.split("a"); System.out.println(Arrays.toString(as)); //统计原字符串里面a出现的次数 System.out.println("a出现的次数:" + (as.length - 1)); //5 前提:最后的a后面要有值 //split(str,limit); //limit>0 limit<=length(a的字符个数) 一共5个a,最多能分6部分 //limit>length 也最多能分length+1个 String[] as1 = s.split("a",1); String[] as2 = s.split("a",2); //用第一个a分割 代表数组元素有两个 String[] as3 = s.split("a",3); String[] as4 = s.split("a",4); String[] as5 = s.split("a",5); String[] as6 = s.split("a",6); String[] as7 = s.split("a",7); System.out.println(Arrays.toString(as1)); //[abcabaaa12] System.out.println(Arrays.toString(as2)); //[, bcabaaa12] System.out.println(Arrays.toString(as3)); //[, bc, baaa12] System.out.println(Arrays.toString(as4)); //[, bc, b, aa12] System.out.println(Arrays.toString(as5)); //[, bc, b, , a12] System.out.println(Arrays.toString(as6)); //[, bc, b, , , 12] System.out.println(Arrays.toString(as7)); //[, bc, b, , , 12] System.out.println("----------------------------"); //limit<0,只要是负数,就会分成最多的份数 String[] as8 = s.split("a",-1); System.out.println(Arrays.toString(as8)); //[, bc, b, , , 12] //limit=0 当数组里面最后的元素为空字符 直接省略 (带一个参数的,默认就是0) String s1 = "abaaa"; String[] str = s1.split("a",0); System.out.println(Arrays.toString(str)); //[, b] //对a后面无值的,统计a出现的次数 String[] str1 = s1.split("a",-1); System.out.println("a出现的次数:" + (str1.length - 1)); //4 } }
5.string常用方法之提取字符串
public class Stringdemo1 { public static void main(String[] args) { demo1(); } private static void demo1() { String str = "吴某凡"; //获得指定索引的字符的内容 char charAt(int index); System.out.println(str.length()); //3 获得字符串里所有字符个数 System.out.println(str.charAt(0)); //吴 //遍历打印字符串里所有字符数据 for (int index = 0; index < str.length(); index++) { System.out.print(str.charAt(index)); } //吴某凡 } }
6.string常用方法之提取字符串
public class Stringdemo1 { public static void main(String[] args) { demo1(); } private static void demo1() { //String substring(int beginIndex) //String substring(int beginIndex, int endIndex) //从指定的索引开始 截取一部分数据 String str = "abcdefg"; String substring = str.substring(3);//从指定的索引开始进行截取 一直到最后 包含开始索引 System.out.println(substring); //defg String substring1 = str.substring(0, 3);//abc 包头不包尾 不包含结束的索引位置 System.out.println(substring1); //场景? String phone = "17767898907"; //长度是固定的 String first = phone.substring(0, 4); String last = phone.substring(7); System.out.println(first + "****" + last); //1776****8907 //给用户看的时候 //数据存储还是17767898907 } }
7.string常用方法之提取字符串
public class Stringdemo1 { public static void main(String[] args) { demo1(); } private static void demo1() { //String trim() 去除字符串左右2端空格 //登录 Scanner input = new Scanner(System.in); System.out.println("请录入字符串:"); String str = input.nextLine(); String s = "hello"; System.out.println(str.trim().equals(s)); //若录入的是 hello,前面多了一个空格,返回仍为true input.close(); String str1 = " ab c "; System.out.println(str1.trim()); //ab c } }
8.string常用方法之字符串替换
public class Stringdemo1 { public static void main(String[] args) { demo1(); } private static void demo1() { //String replace(char oldChar, char newChar) //String replace(CharSequence target, CharSequence replacement) // //String replaceAll(String regex, String replacement) 替换所有满足正则语法要求的字符串数据 //String replaceFirst(String regex, String replacement) 替换第一个满足正则语法要求的字符串数据 String str = " ab c "; //替换 将所有的空格都去除掉 第一个不行(是char类型) System.out.println(str.replace(" ", "")); //abc 第二个(字符接口,多态了) System.out.println(str.replaceAll(" ", "")); //abc 第三个 System.out.println(str.replaceFirst(" ", "")); // ab c 第四个只替换了第一个(用的很少) //替换必须与正则一块使用 } }
9.string常用方法之字符串比较判断
public class Stringdemo1 { public static void main(String[] args) { demo1(); } private static void demo1() { //boolean equals(Object anObject) 比较2个字符串数据是否相等 //int compareTo(String anotherString) 0 正数 负数 //boolean equalsIgnoreCase(String anotherString) //不区分大小写进行 比较 //boolean contains(CharSequence s) //判断字符串那里面是否包含指定的字符串的数据 也用的不多 //boolean isEmpty() // 判断字符串是否是空字符 //boolean startsWith(String prefix) //判断字符串是否以指定数据开头 //boolean endsWith(String suffix) //判断是否以指定的字符串结尾 判断文件后缀居多 //比较的底层走的是相同索引的元素必须相同 String a = "abc"; String b = "edf"; System.out.println(a.compareTo(b)); //-4 返的是2个字符相减的结果(a-e=-4) 用的不多 //录入验证码 String code1 = "AEFD12"; String code2 = "aefd12"; System.out.println(code1.equalsIgnoreCase(code2)); //true System.out.println("hello".contains("abc")); //false //拿字符串第一个字符数据 不能直接charAt(0); String s = ""; Objects.requireNonNull(s); //提前预判 if (s.isEmpty()) { //s.isEmpty()等价于s.length()==0 return; } System.out.println(s.charAt(0)); //上传文件 //*.jpg String path = "C:\\a.txt"; Objects.requireNonNull(path); if (path.isEmpty()) { return; } if (!path.endsWith("txt")) { //判断是否以txt结尾 return; } System.out.println("文件上传功能......"); } }
10.string常用方法之字符串搜索
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { //int indexOf(String str) 获得指定字符串第一次出现的索引位置 没有找到指定的字符 返回值 -1 //int indexOf(String str, int fromIndex) //int lastIndexOf(String str) 获得指定字符串最后一次出现的索引位置 没有找到指定的字符 返回值 -1 //int lastIndexOf(String str, int fromIndex) String str = "abcdabc"; //获得字符a第一次出现的索引位置 int index = str.indexOf("a"); System.out.println(index); //0 int index1 = str.indexOf("a", 3); //从指定索引处 查询指定字符串第一次出现的索引位置 System.out.println(index1); //4 //获得字符a最后一次出现的索引位置 int lastIndex = str.lastIndexOf("a"); System.out.println(lastIndex); //4 int lastIndex1 = str.lastIndexOf("a", 3); //从后往前找呢 System.out.println(lastIndex1); //0 } }
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { String str = "abaaacdabc"; //需求: 使用indexOf或者lastIndexOf 求指定字符串出现次数 //a int count = 0; int startIndex = 0; while (true) { int index = str.indexOf("a", startIndex); if (index == -1) { break; } count++; startIndex = index + 1; } System.out.println("a出现的次数:" + count); } }
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { String filePath = "D:\\demo\\a\\b\\a.jpg"; //获得文件名称 //String[] array = filePath.split("\\\\"); 上面是\\,一个\用一个转义\,故四个\ 用\分割。得到分割后的数组,最后一个元素就是文件名 //System.out.println(array[array.length - 1]); //核心: 找最后一个\\出现的索引位置 //法二: String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1); //用截取,记得包头不包尾,不需要\ System.out.println(fileName); } }
11.string常用方法之其他
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { //String intern() //static String join(CharSequence delimiter, CharSequence... elements) 静态方法,功能等价于concat,将多个字符串追加成一个字符串 //String toLowerCase() 对指定字符串进行小写转换 //String toUpperCase() 对指定字符串进行大写转换 //String.valueOf(); 将其他类型的数据转换成String String str = "Abedf"; System.out.println(str.toUpperCase().toLowerCase()); //ABEDF String s = String.valueOf(100.123); System.out.println(s); //100.123 //执行用户注册,最后文件的格式是1001-张三-30-1234。如何变成这样的数据 //录入id,name,age,pass,然后拼接 Scanner input = new Scanner(System.in); System.out.println("请录入id:"); int id = input.nextInt(); System.out.println("请录入name:"); String name = input.next(); System.out.println("请录入age:"); String age = input.next(); System.out.println("请录入pass:"); String pass = input.next(); //String userInfoStr = id + "-" + name + "-" + age + "-" + pass; //1001-张三-30-1234 法一 //id.concat("-").concat(name).concat("-") //法二 //法三:join //join() 连接,使用特定分隔符将多个字符序列连接在一起,成为新的字符串 //String join(CharSequence delimiter, CharSequence... elements) 分隔符(自定义的),可变参数(是个数组,要传同一类型,可传多个) String userInfoStr = String.join("-", String.valueOf(id), name, age, pass); //id是int型,转String,可拼接,也可装箱 System.out.println(userInfoStr); //1001-张三-30-1234 } }
12. string常用方法之其他
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { //String intern() 获得指定字符串的一个副本,获得常量池内存地址 String str = "hello"; //hello存在常量池 String intern1 = str.intern(); System.out.println(intern1 == str); //true System.out.println("--------------------"); String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(str1 == str2); //false System.out.println(str == str1); //false System.out.println("========================"); String str1Intern = str1.intern(); System.out.println(str1Intern == str1); //false System.out.println(str2 == str2.intern()); //false System.out.println(str1.intern() == str2.intern()); //true System.out.println(str == str1.intern()); //true } }
public class StringDemo2 { public static void main(String[] args) { demo1(); } private static void demo1() { //只要其中一个字符串变量和字符串(不管是常量,eg:"a " 还是变量名 a)拼接,全都产生新的字符串对象,等价于new了一个新的 String a = "a"; String b = "b"; String ab = "ab"; String ab1 = new String("ab"); System.out.println((a+b) == ab); //false (a+b)又变成了一个新的变量,底层做的StringBulder的拼接 System.out.println(ab == ab1); //false 一个在常量池,一个在堆 System.out.println((a + "b") == ab); //false System.out.println((a + b) == ab1); //false System.out.println(("a" + "b") == "ab"); //true 两个常量在常量池,合成一个ab System.out.println(("a" + "b") == ab); //true 和上面一个意思 //在程序运行期间,下面有几个字符串引用(对象)? String str = new String("abc"); //str是一个,指向堆内存new的数据 "abc"是一个,是常量引用,维护常量池内存(前提,常量池没有"abc",第一次走) } }
13. 正则表达式
String[] split(String regex);
String replaceAll(String regex, String replacement)
String replaceFirst(String regex, String replacement)
boolean matches(String regex)
public class RegexDemo { public static void main(String[] args) { regexDemo1(); } private static void regexDemo1() { //用户名规则:首字母必须大写(只能是一个),接下来由3-5个小写字母组成,接下来必须有1个下划线_(在小写字母后面),接下来有2-5个数字 String username = "Jimmy_123"; //假设这是拿到的用户名 //校验用户名是否满足规则(模式)。 String regex = "^([A-Z]{1})([a-z]{3,5})([_]{1})([0-9]{2,5})$"; //正则去写 //优化 regex = "^[A-Z][a-z]{3,5}_\\d{2,5}$"; // [0-9]可以被\d替换,这里还要转义,加一个\ //校验: Patten类代表正则,可以校验正则的语法是否ok Patten类作用:正则表达式的编译表示。(校验正则的语法是否ok) //Patten类在java.util.regex.Pattern /*Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(username); boolean flag = matcher.matches(); System.out.println(flag);*/ //判断一个文本数据是否满足正则模式的需求 System.out.println(username.matches(regex)); } }
public class RegexDemo { public static void main(String[] args) { regexDemo1(); } private static void regexDemo1() { String phoneStr = "15278681234"; //1.校验手机号码是否是合法的 String phoneRegex = "^1[3-9]\\d{9}$"; //手机号正则 if (!phoneStr.matches(phoneRegex)) { System.out.println(phoneStr + "不合法"); return; } //2.隐藏手机号中间的4位数字为**** //String replaceAll(String regex, String replacement) //若动态获得原字符串里面的一部分,这个时候必须使用() String regex = "^(\\d{3})\\d{4}(\\d{4})$"; //中间是4个数字,0-9 前面后面两部分必须加() System.out.println(phoneStr.replaceAll(regex, "$1****$2")); //参数是正则和替换的内容 替换环境中$n代表的是第n个域里的内容 } }
public class RegexDemo { public static void main(String[] args) { regexDemo1(); } private static void regexDemo1() { String path = "C:\\a\\b\\c.txt"; //使用\分隔字符串 System.out.println(Arrays.toString(path.split("\\\\"))); //也是正则参数 String fileName = "a.jpg"; System.out.println(Arrays.toString(fileName.split("\\."))); //一个点在正则里是任意一个单字符,当为普通点,也需要转义 } }
public class RegexDemo { public static void main(String[] args) { regexDemo1(); } private static void regexDemo1() { //去重 //需求:去掉重复的字符的数据,保留唯一字符 String str = "abaa乌克克克克克aacccc乌克克克克克兰兰兰兰"; //分析: 1. 循环遍历字符串 获得每个字符 for charAt(index) //2. 创建容器 存储唯一的字符 数组 int length = str.length(); char[] weiYiArray = new char[length]; //维护唯一的字符的数据 int newIndex = 0; for (int index = 0; index < length; index++) { char c = str.charAt(index); //得到了每一个字符数据 boolean flag = false; for (int i = 0; i < newIndex; i++) { if (weiYiArray[i] == c) { flag = true; //重复的不要,结束当前循环 break; } } //有条件的:c字符唯一,重复的不放入 if (!flag) { weiYiArray[newIndex++] = c; //将字符放到数组 } } /* weiYiArray = Arrays.copyOf(weiYiArray,newIndex); System.out.println(Arrays.toString(weiYiArray));*/ String s = new String(weiYiArray, 0, newIndex); //从0开始,newIndex个字符 System.out.println(s); } }
public class RegexDemo { public static void main(String[] args) { regexDemo1(); } private static void regexDemo1() { //去重 //需求:去掉重复的字符的数据,保留唯一字符 用正则去写 String str = "abaa乌克克克克克aacccc乌克克克克克兰兰兰兰"; char[] chars = str.toCharArray(); //字符串可以转数组 Arrays.sort(chars); //排序 str = new String(chars); //数组转字符串 System.out.println(str); //aaaaabccccddd乌乌克克克克克克克克克克兰兰兰兰 //String replaceAll(String regex, String replacement) 前提: 满足字符数据是连贯的 //如何去重:使用一个唯一字符替换重复n次字符数据 (a替换所有的a) String regex = "(.)\\1+"; //点代表任意字符 多次替换: 不允许使用 ^ $ (开头,结尾) +只能限定前面的[]内容 \n代表第n个小括号内容 //这个整体是说,有多个相同字符 System.out.println(str.replaceAll(regex, "$1")); //用任意一个字符替换多个相同字符 } }
14. StringBuffer/StringBuilder
与String一致。代表的是字符串。 值是可变的。 可变的字符序列。
这两个类里面的方法一模样
public class StringBuilderDemo { public static void main(String[] args) { //1.创建StringBuilder对象 StringBuilder builder = new StringBuilder(); //可变的字符序列,必须new System.out.println(builder); //空字符 //常用的功能方法 StringBuilder builder1 = new StringBuilder("hello"); /* builder1.append("abc"); //在末尾追加,参数可以是任意类型数据 System.out.println(builder1); //helloabc*/ /*builder1.insert(0,"abc"); //指定位置插入 System.out.println(builder1); //abchello*/ /*//删除第一个l,怎么做? /*builder1.deleteCharAt(builder1.indexOf("l")); // 删除指定索引的字符数据 System.out.println(builder1); //helo*/ //删除前三个字符 /*builder1.delete(0,3); //删除指定索引范围内数据(包头不包尾) System.out.println(builder1); //lo*/ //将前三个字符换成abc /*builder1.replace(0,3,"abc"); System.out.println(builder1); //abclo*/ //翻转字符串 /*builder1.reverse(); System.out.println(builder1); //olleh*/ } }
1.6课后作业
1.用户从控制台输入一个字符串,要求判断是否为合法的email地址,如果合法,请判断是否为sina的邮箱地址。
(PS:记住异常处理) 合法邮箱规则: 有且仅有一个@和. @在.之前 且@不能是第一位 .不能是最后一位 @与.不能相邻 新浪邮箱应当以@sina.com结尾
public class Exercise1 { public static void main(String[] args) { demo1(); } //用正则去写 private static void demo1() { String email = "12345@qq.com"; Objects.requireNonNull(email,"请提供有效的邮箱数据"); String emailRegex = "^\\w{5,}@\\w{2,}.[a-zA-Z]{2,3}$"; // \w匹配0-9,A-Z,a-z,以及下划线内容 {5,}限定最少5个,最多不限 //正则里 "."匹配单字符,需要普通的点需要转义(放在大括号里需要转义),外面固定的不用转义 if(!email.matches(emailRegex)){ throw new RuntimeException(email + "不符合邮箱规则"); } System.out.println(email + "是一个合法邮箱"); String sinaEmailRegex = "^\\w{5,}@sina.com$"; if(!email.matches(sinaEmailRegex)){ throw new RuntimeException(email + "不符合sina邮箱规则"); } System.out.println(email+"是一个合法sina的邮箱"); } }
public class Exercise102 { public static void main(String[] args) { demo2(); } //用String功能去写 private static void demo2() { String email = "12345@qq.com"; Objects.requireNonNull(email); //有且仅有一个@和. int index1 = email.indexOf("@"); int lastIndex1 = email.lastIndexOf("@"); int index2 = email.indexOf("."); int lastIndex2 = email.lastIndexOf("."); //提前预判 if(index1 == -1 || index2 == -1){ throw new RuntimeException(email + "不符合邮箱规则"); } boolean flag1 = (index1 == lastIndex1) && (index2 == lastIndex2); //@在.之前 且@不能是第一位 .不能是最后一位 @与.不能相邻 boolean flag2 = (index1 != 0) && (index2 != email.length()-1) && (index2-index1>1); if(!flag1 || !flag2){ throw new RuntimeException(email + "不符合邮箱规则"); } System.out.println(email+"是一个合法的邮箱"); //新浪邮箱应当以@sina.com结尾 if(!email.endsWith("@sina.com")){ throw new RuntimeException(email + "不符合sina邮箱规则"); } System.out.println(email+"是一个合法sina的邮箱"); } }
2.用户从控制台输入一个字符串,请判断是否为回文字符串。
(noon level abcba)
public class Exercise2 { public static void main(String[] args) { demo3(); } private static void demo3() { String str = "abcba"; Objects.requireNonNull(str); StringBuilder builder = new StringBuilder(str); builder.reverse(); if(str.equals(builder.toString())){ //equals底层要求参数是String,否则返false,即这个if不执行 System.out.println(str + "是一个回文字符串"); }else { System.out.println(str + "不是一个回文字符串"); } //不用reverse()也可以,逆向遍历,拼接成一个字符串,再和原字符串equals //for (int index = str.length()-1 ; length > 0 ; length--) { // } } }
3.编写自定义的字符串一致性匹配方法,只要两个字符串包含同样的字符,不管字符的顺序如何,都认为两个字符串一致
如:”aabbcc”和”abcabc”被认为是一致的
public class Exercise3 { public static void main(String[] args) { demo3(); } private static void demo3() { String str1 = "aabbcc"; String str2 = "abcabc"; Objects.requireNonNull(str1); Objects.requireNonNull(str2); int length1 = str1.length(); int length2 = str2.length(); if(length1 != length2){ return; } //转换成字符数组 char[] chars1 = str1.toCharArray(); char[] chars2 = str2.toCharArray(); Arrays.sort(chars1); Arrays.sort(chars1); //比较相同索引处的字符数据是否一致 /*for(int index = 0;index <= length1;index++){ if(chars1[index] != chars2[index]){ System.out.println(str1 + "与" + str2 + "数据不同"); return; } } System.out.println(str1 + "与" + str2 + "数据相同");*/ System.out.println(Arrays.equals(chars1, chars2)); } }
public class Exercise301 { public static void main(String[] args) { demo3(); } private static void demo3() { String str1 = "aabbcc"; String str2 = "abcabc"; StringBuilder builder = new StringBuilder(str2); //遍历str1,遍历一个删除str2一个 int length = str1.length(); for (int index = 0; index < length; index++) { char c = str1.charAt(index); int cIndex = builder.indexOf(String.valueOf(c)); //拿到了c的Index if( cIndex == -1 ){ System.out.println("两个字符串不等"); return; } builder.deleteCharAt(cIndex); //删除指定索引位置的字符数据 } if(builder.length()==0){ System.out.println("两个字符串相等"); } } }
4.从控制台实现输入字符串(路径),分别把盘符,文件路径(不包含盘符),文件名,文件类型打出来
如: E:\jboss-4.0.4.GA\server\minimal\conf\readme.txt 解析路径,输入 盘符,文件路径,文件名,文件类型。 盘符:E: 文件路径:jboss-4.0.4.GA\server\minimal\conf\ 文件名:readme 文件类型:txt*/
public class Exercise4 { public static void main(String[] args) { demo4(); } private static void demo4() { String path = "E:\\jboss-4.0.4.GA\\server\\minimal\\conf\\readme.txt"; int index1 = path.indexOf("\\"); int lastIndex1 = path.lastIndexOf("\\") + 1; int lastIndex2 = path.lastIndexOf("."); System.out.println("盘符:" + path.substring(0, index1)); System.out.println("文件路径:" + path.substring(index1 + 1, lastIndex1)); System.out.println("文件名:" + path.substring(lastIndex1, lastIndex2)); System.out.println("文件类型:" + path.substring(lastIndex2 + 1)); } }
5.把数组中的数据按照指定格式拼接成一个字符串。
举例:int[] arr = {1,2,3}; 输出结果:[1, 2, 3]
public class Exercise5 { public static void main(String[] args) { demo5(); } private static void demo5() { int[] arr = {1, 2, 3}; System.out.println(Arrays.toString(arr)); StringBuilder builder = new StringBuilder(); builder.append("["); /*for (int num : arr) { builder.append(num).append(","); } builder.append("]");*/ int length = arr.length; for (int index = 0; index < length; index++) { builder.append(arr[index]); if (index == length - 1) { builder.append("]"); break; } builder.append(", "); } //builder.deleteCharAt(builder.lastIndexOf(",")); System.out.println(builder); } }
6.去掉一个字符串中的所有空格(包括中间的空格) 使用正则
public class Exercise6 { public static void main(String[] args) { demo6(); } private static void demo6() { String str = " j d o "; System.out.println(str.replace(" ", "")); System.out.println(str.replaceAll(" ", "")); System.out.println(str.replaceAll("\\s+", "")); } }
7.让用户在控制台不断录入英文字母(每次录入两个字母即可),直到总长度超过6个停止,然后统计一下一共有几个a
public class Exercise7 { public static void main(String[] args) { demo7(); } private static void demo7() { Scanner input = new Scanner(System.in); StringBuilder builder = new StringBuilder(); String regex = "^[a-zA-Z]{2}$"; while (builder.length() < 6) { System.out.println("录入英文字母(两个字母):"); String str = input.nextLine(); if (!str.matches(regex)) { System.out.println("录入数据不合法 请重新录入"); continue; } builder.append(str); } String str = builder.toString().toLowerCase(); System.out.println(str.split("a", -1).length - 1); } }
8.让用户在控制台输入几个文件名,中间用“,”隔开,然后只把jpg文件换行输出来。
例如: hello.java,a.txt,x1.jpg,t1.ppt,m.jpg
public class Exercise8 { public static void main(String[] args) { demo8(); } private static void demo8() { String fileNames = "hello.java,a.txt,x1.jpg,t1.ppt,m.jpg"; String[] nameArray = fileNames.split(","); for (String name : nameArray) { if(name.endsWith("jpg")){ System.out.println(name); } } } }
9.现有一个字符串“我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程”。将该字符串变成:“我要学编程”。使用正则
public class Exercise9 { public static void main(String[] args) { demo9(); } private static void demo9() { String str = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程"; System.out.println(str.replaceAll("\\.+", "").replaceAll("(.)\\1+","$1")); } }
1.7lang包,String包总结
1.lang包常用类
- 包装类---->基本数据类型
Integer num = 100; //自动装箱 Integer.valueOf(int num)
int a = num; //自动拆箱 引用.xxxValue();
整数缓存池(减少内存的开销)----> Byte Short Long Integer Character
-128-127 IntegerCache.cache[] (Byte Short Long)
0-127 Character.cache[]
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1.equals(num2));
System.out.println(num1.hashCode());//返回的还是数据的本身
System.out.println(num2.hashCode());//返回的还是数据的本身
System.out.println(num1.compareTo(num2));
/* String str1 = "hello";
String str2 = "hello";
System.out.println(str1.equals(str2));*/
其他类型数据与String之间相互转换
String numStr = "123";
转整型
Integer num = Integer.parseInt(numStr);
Character
将指定字符转换成指定进制数字
char c = '1';
int digit = Character.digit(c, 10);
Object 1.比较对象为啥要重写equals+hashcode? 比较: == equals 默认执行的Object == 子类自定义比较规则 (重写equals) 2个对象比较true 他们的hash值也必然是相同的 仅仅只是重写一个equals 无法满足哪个规则 重写hashcode 2个对象的hash不同 可以直接认为2个对象就是不等的,为什么不直接使用hash进行比较? hash的效率比较高 只是执行一些算术运算 hash算法原因: 2个数据不等的变量 有可能2个对象hash值是一样的。 2.克隆对象 clone 1. 实现 必须实现一个标记接口 Cloneable-----> CloneNotSupportException 2. 子类重写父类的clone 3. 克隆默认是深克隆还是浅克隆? 浅克隆 4. 深克隆 VS 浅克隆 引用数据类型: 浅克隆 复制内存地址值 一个对象的额数据改变 会影响另外一个对象数据 深克隆: 获得数据。 克隆对象成功: 克隆的对象与原对象不是同一个对象 也没有执行相关的构造。
3.获得Class类对象的3种方式
3.1 Class getClass()
3.2 引用类型.class
3.3 Class.forName("类类型的完整路径(包名+类名)");
4.GC可以回收哪些引用关联的对象?
4.1 强引用 软 弱 虚
2. String方法总结
功能方法 | 作用 |
String[ ] split(String regex) | 使用指定的字符串分割原字符串的数据。 |
String[ ] split(String regex,int limit) | 0: 末尾空字符串 直接省略 -1: 获得所有分割出来的数据 |
char charAt(int index) | 查询指定索引的字符数据。index>=0 index<=length()-1 |
String replace(char target,char replace); | 使用指定字符数据替换原字符串里面所有的指定的字符数据 |
String replaceAll(String regex,String str); | 使用指定字符串替换满足正则模式规则的文本数据 |
String replaceFirst(String regex,String st) | |
int indexOf(String str) | 查询指定字符串第一次出现的索引位置。 -1 |
int lastIndexOf(String str); | 查询指定字符串最后一次出现的索引位置。-1 |
boolean equals(Object obj); | 比较2个字符串的数据是否相等 |
String subString(int stratIndex,int endIndex) | 截取指定索引字符串数据(包头不包尾) |
char[] toCharArray(); | 将字符串转换成字符数组 |
boolean contains(String str); | 判断是否包含指定字符串数据 |
boolean endWith(String str); | 判断字符串是否以指定字符串结尾 |
boolean startWith(String str); | 判断字符串是否以指定字符串开头 |
String concat(String str) | 在原字符串末尾追加指定的字符串数据 |
static String valueOf(int num); | 将指定的数据转换字符串 |
boolean equalsIgnoreCase(String str); | 不区分大小写比较2个字符串的数据是否一致 |
boolean matches(String regex); | 比较指定字符串是否满足指定模式规则 |
static String join(String delimeter, String...strs); | 连接/拼接 将多个字符串数据使用分隔符连接在一起 |
String toUpperCase(); | 大写转换 |
String toLowerCase() | 小写转换 |
byte[ ] getBytes(); | 编码。将字符串转换成平台默认编码格式下的字节数组。 |
byte[ ] getBytes(String charSet); | |
byte[ ] getBytes(Charset charSet); | |
String trim(); | 去除首尾空格 |
String intern() | 获得常量池数据引用 |
boolean isEmpty(); | 判断字符串是否是空串(不包含空格) |
int length(); | 获得字符串里面字符个数 |
int compareTo(String str) | 0 正数 负数 |
boolean isBlank(); | 判断字符串是否是空(包含空格) |
3. StringBuilder独有的方法:
功能方法 | 作用 |
StringBuilder reverse() | 翻转 |
StringBuilder append(String str); | 末尾拼接 |
StringBuilder insert(int index,String str); | |
StringBuilder delete(int start,int end); | 删除指定索引范围内的数据 |
StringBuilder deleteCharAt(int index); | 删除指定索引字符数据 |
StringBuilder replace(int start,int end,String str); | |
void``setCharAt(int index, char ch) |