一常用API ——第四节、String类,Static静态
一、字符串概述和特点
String位于java.lang包下,因此不需要导入
API当中说,java程序中所有字符串字面值如“abc”都作为此类的实例实现,其实就是说;程序中所有的双引号字符串,都是String类的对象,就算没有new,也是
字符串的特点:
1、字符串的内容用不可变,【重点】
2、正是因为字符串不可改变,所有字符串可以共享使用
3、字符串效果上相当于char[]数组,底层原理是byte[]字节数组
创建字符串的常见3+1种方式
三种构造方法,
public String():创建一个空白字符串,不含有任何内容。
public String(char[] array):根据字符数组的内容,来创建对应的字符串。
public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
一种直接创建
String str = "hello";//右边直接用双引号
注意:直接写上双引号,就是字符串对象
二、字符串的构造方法和直接创建
package cn.day07.demo05;
public class Demo01String {
public static void main(String[] args) {
//使用空参构造
String st1 = new String();
System.out.println("第一个字符串:" + st1); //第一个字符串:
//根据字符数组创建字符串
char[] arr = {'A', 'B' ,'C'};
String str2 = new String(arr);
System.out.println("第二个字符数组:" + str2 ); //第二个字符数组:ABC
//根据字节数组创建字符串
byte[] bytes = {97,98,99};
String str3 = new String(bytes);
System.out.println("第三个字节数组:" + str3); //第三个字节数组:abc
//直接创建
String str4 = "stting";
System.out.println("第四个字符串:" + str4);
}
}
三、字符串的常量池
程序当中直接写上的双引号字符串,就在字符串常量池中。
对于基本类型来说,==是进行数值的比较,
对于引用类型来说,==是进行【地址值】的比较
字符串比较
四、字符串的比较相关方法
package stringDemo;
/*
== 时进行对象地址值的比较,如果需要字符串比较, 可以使用两个方法:
一、public boolean equals(Object obj).参数可以是任何对象,只有参数是一个字符串并且内容相同,返回true。注意事项:
1、任何对象都能用Object接收。
2、equals方法有对称性,也就是a.equals(b)和b.equals(a) 效果一样
3、如果比较双方,一个常量,一个变量,推荐把常量写在前面,推荐“abc”.equals(str),不推荐str.equals("abc")
二、public boolean equalsIgnoreCase(String str),忽略大小写,进行内容比较
*/
public class EqualsDemo {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
char[] arrArray = {'h','e','l','l','o'};
String str3 = new String(arrArray);
System.out.println(str1.equals(str2)); //true
System.out.println(str1.equals(str3)); //true
System.out.println(str1.equals("hello")); //true
System.out.println("hello".equals(str1)); //推荐 true
String str5 = null;
System.out.println("abc".equals(str5)); //推荐,false
System.out.println(str5.equals("abc")); //不推荐,报错,空指针异常。java.lang.NullPointerException
System.out.println("+++++++++");
String str6 = "HELLO";
System.out.println("hellO".equalsIgnoreCase(str6)); //true,忽略大小写
}
}
true
true
true
true
五、字符串的获取相关方法
String 当中与获取相关的常用方法:
public int length();获取字符串当中含有的字符个数,拿到字符换长度
public String concat(String str): 将当前字符串和参数字符串拼接,返回新的字符串
public charAt(int index):获取指定索引位置的单个字符。(索引从0 开始)
public int index(String str):查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回-1值。
六、字符串的截取方法
public String substring(int index);截取从参数位置一直到字符串末尾,返回新字符串
public String subString(int begin , int end);截取从begin到end ,左闭右开
七、String当中与转换相关的常用方法有:
public char[] toCharArray():将当前字符串拆分成为字符数组作为返回值
public byte[] getBytes():获得当前字符串底层的字节数组
public String replace(charSequene oldString,charSequene new String):将所有老字符串替换成新字符串,返回替换之后的新字符串
八、字符串的分割方法
public String[] split(String regex);按照参数的规则,将字符串切割成若干部分
/split 方法的参数其实是一个正则表达式,今天要注意如果按照英文句点.切割,按照\.切
2、所有方法
package stringDemo;
public class Stringfangfa {
public static void main(String[] args) {
String s = "hellowohellowohellowo";
System.out.println("长度:" + s.length()); //21
System.out.println("拼接:" + s.concat("fd")); //新的字符串
System.out.println("llo第一次出现的索引:" + s.indexOf("llo")); //2
System.out.println("yui第一次出现的索引;" + s.indexOf("yui")); //-1
System.out.println("索引为1的字符:" + s.charAt(1)); //e
System.out.println("截取从这个位置到末尾:" + s.substring(3)); //lowohellowohellowo
System.out.println("截取中间 ,左闭右开:" + s.substring(3,5) ); //lo
char[] chars = s.toCharArray();
System.out.println("拆分成字符数组:" + chars[2]); //l
byte[] bytes = ”abc“.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]); // 97 98 99
}
//字符串的内容替换,原来的字符串不变,生成了一个新的字符串
System.out.println("替换后:" + s.replace("l","p")); //heppowoheppowoheppowo
//切割
//split 方法的参数其实是一个正则表达式,今天要注意如果按照英文句点.切割,按照\\.切
String s1 = "aa,bb,gg";
String[] str = s1.split(",");
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]); //aa bb gg
}
System.out.println("=====");
String s2 = "aa.bb.gg";
String[] str3 = s2.split(".");
System.out.println(str3.length) //数组长度是0
String[] str2 = s2.split("\\.");
for (int i = 0; i < str2.length; i++) {
System.out.println(str2[i]); // aa bb gg
}
}
}
例子、拼接几个字符串
package stringDemo;
/*
定义一个方法,把数组{1,2 ,3} 按照指定格式拼成一个字符串,格式[word1#word2#word3]
思路:
1\准备一个int[] = {1,2,3}
2\定义一个方法 把数组换成子字符串
三要素:
返回值,String
方法名 getString
参数列表 arr[]
3\[word1#word2word3]
用到for循环,拼接,每个数组元素前有word.分隔用的是#,区分是不是最后一个
4、调用方法,返回结果,打印结果字符串
*/
public class Demo1pingjie {
public static void main(String[] args) {
int[] a = {1, 2, 3};
String result = getString(a);
System.out.println(result);
}
public static String getString(int arr[]) {
String str = "[";
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
str += "word" + arr[i] + "]";
} else {
str += "word" + arr[i] + "#";
}
}
return str;
}
}
例子、统计各个字母个数
题目:键盘输入一个字符串,统计其中各种字符出现的次数
种类有:大写字母,小写字母,数字,其他
思路:
1、既然用到键盘输入,肯定有Scanner
2、键盘输入的是字符串,那么String str = sc.next()'
3、定义四个变量。分别代表四种字符各自出现的次数
4、需要对字符串一个个检查,String--char[], 用toCharArray()
5、遍历char[],字符数组,对当前字符串的种类进行判断,并且用四个变量进行++动作,
6、打印出四个变量,分别代表四种字符出现次数。
package stringDemo;
import java.util.Scanner;
public class Demo4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String input = sc.next();
int countLow= 0;
int countUpper = 0;
int countNum = 0;
int countother = 0;
char[] arr = input.toCharArray();
for (int i = 0; i < arr.length; i++) {
char ch = arr[i];
if ('A' <= ch && ch <= 'Z') {
countUpper++;
}else if('a' <= ch && ch <= 'z'){
countLow++;
}else if('0' <= ch && ch <= '9'){
countNum++;
}else {
countother++;
}
}
System.out.println("大写:" + countUpper + "小写:" + countLow + "数字:" + countNum + "其他:" + countother) ;
}
}
package stringDemo;
/**
* created by apple on 2020/6/8
* 大小写出现的次数
*/
public class Demo5 {
public static void main(String[] args) {
String s = "asdASD123<>?";
int low = 0;
int up = 0;
int num = 0;
int other = 0;
for (int i = 0; i < s.length(); i++) {
char ch= s.charAt(i);
if ('A' <= ch && ch<='Z'){
up++;
}else if
('a' <= ch && ch<= 'z'){
low++;
}else if ('0' <= ch && ch <='9'){
num ++;
}else {
other++;
}
}
System.out.println("大写:" + up + "小写" + low + "数字" + num + "其他" + other);
}
}
static 静态
一、静态static关键字概述
概述二、静态static关键字修饰成员
package staticDemo;
public class Student {
private int age;
private String name;
static String room; //教师
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
public Student() {
}
}
package staticDemo;
public class StudentDemo {
public static void main(String[] args) {
Student stu1 = new Student("g",19);
stu1.room = "101教是";
Student stu12= new Student("s",18);
System.out.println("姓名" + stu1.getName() + "年龄" + stu1.getAge() + "教是" + stu1.room);
System.out.println("姓名" + stu12.getName() + "年龄" + stu12.getAge() +"教是" + stu12.room);
}
}
输出:
姓名g年龄19教是101教是
姓名s年龄18教是101教是
例子:学号自动递增
package cn.day08.demo03;
public class Student {
private int id; //学号,自动生成
private int num;
private String name;
static String room; //所在教室
private static int idCounter = 0; //学号计数器,每当new一个新对象,计数器++
public Student() {
idCounter++;
}
public Student(int num, String name) {
this.num = num;
this.name = name;
this.id=++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package cn.day08.demo03;
/*
如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类,多个对象共享同一份数据
*/
public class Demo01StaticField {
public static void main(String[] args) {
Student one = new Student(19,"黄");
one.room = "101教室";
System.out.println(one.getName()+ one.getNum()+ one.room + "学号:" + one.getId()); //黄19101教室学号:1
Student two =new Student(20,"白");
System.out.println(two.getName()+ two.getNum() + two.room + "学号:" + two.getId()); //白20101教室学号:2
}
}
三、static关键字修饰方法
package cn.day08.demo03;
public class MyClass {
int num ;//成员变量
static int numstatic ; //静态变量
//成员方法
public void method(){
System.out.println("成员方法");
System.out.println(num); //成员方法可以访问成员变量
System.out.println(numstatic); //成员方法可以访问静态变量
}
//静态方法
public static void methodStatic(){
System.out.println("静态方法");
// System.out.println(num); 错误写法,静态方法不可访问非静态【重点】
System.out.println(numstatic); //静态方法可以访问静态变量
//静态方法中不能使用this 关键字
System.out.println(this); //错误写法
}
}
package cn.day08.demo03;
/*
一旦使用static修饰成员方法,那么这个方法就变成了静态方法,静态方法不属于对象,而是属于类的
如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它
如果有了static关键字,那么不需要创建对象,直接就能通过类名称使用它
无论是成员变量,还是成员方法,如果有了static ,都推荐用类名称进行调用
静态变量:类名称.静态变量
静态方法:类名称.静态方法()
注意事项:
1、静态不能直接访问非静态
原因:因为内存当中是【先】有的静态内容,【后】有的非静态内容
"先人不知道后人,后人知道先人"
2、静态方法当中不能用this
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象
*/
public class Demo02StaticMethod {
public static void main(String[] args) {
MyClass myClass = new MyClass(); //首先创建对象
myClass.method(); //然后才能使用没有static关键字的方法 成员方法
//对于静态方法来说,可以通过对象名调用,也可直接通过类名调用
myClass.methodStatic(); //不推荐,这种写法在编译之后也会被java翻译成类名称.静态方法 静态方法
MyClass.methodStatic(); //推荐 静态方法
//对于本类当中的静态方法,可以省略类名称
myMethod(); // 自己的方法
Demo02StaticMethod.myMethod(); //完全等效 自己的方法
}
public static void myMethod(){
System.out.println("自己的方法");
}
}
四、静态static的内存图
为啥教室可以共享
静态
五、静态代码块
package cn.day08.demo03;
import javax.swing.plaf.synth.SynthOptionPaneUI;
/*
静态代码块的格式
public class 类名称{
static {
//静态代码块
}
}
特点:
当第一次用到本类时,静态代码块执行唯一的一次
*/
public class Person {
static {
System.out.println("静态代码块块");
}
public Person(){
System.out.println("构造方法执行");
}
}
package cn.day08.demo03;
/*
静态代码块的格式
public class 类名称{
static {
//静态代码块
}
}
特点:
当第一次用到本类时,静态代码块执行唯一的一次
静态内容总是优先于非静态。,所有静态代码块比构造方法先执行
静态代码块的典型用途:
用来一次性的对静态成员变量进行赋值
*/
public class Demo04Static {
public static void main(String[] args) {
Person one = new Person(); // 静态代码块块 构造方法执行
Person two = new Person() ; //构造方法执行
}
}