字符串概述和特点
程序当中所有的双引号字符串,都是String类的对象
字符串的特点:
1.字符串的内容永不可变
2.正是因为字符串不可改变,所有字符串是可以共享使用的
3.字符串效果上相当于是char[ ]字符数组,但是底层原理是byte[ ]字节数组
创建字符串的常见3+1种方式
三种构造方法:
public String(): 创建一个空白字符串,不含有任何内容
public String(char[ ] array): 根据字符数组的内容,来创建对应的字符串
public String(byte[ ] array):根据字节数组的内容,来创建对应的字符串
一种直接创建:
String str = “hello”
package demo1;
public class t1 {
public static void main(String[] args) {
//使用空参构造
String str1 = new String();
//根据字符数组创建字符串
char[] charArray = {'A','B','C'}; //注意char类型使用单引号
String str2 = new String(charArray);
//根据字节数组创建字符串
byte[] byteArray = {97,88,56};
String str3 = new String(byteArray);
//直接创建
String str4 = "hello";
}
}
字符串的常量池
上面我们说到字符串是可以共享使用的,那么如何共享?这里就引入了一个概念常量池.
- 字符串常量池:程序当中直接写上的双引号字符串,就在字符串常量池中
new的不在池当中 - 对于基本类型来说, ==是进行数值的比较
对于引用类型来说,==是进行地址值的比较
package demo1;
public class t1 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
char[] charArray = {'a','b','c'};
String str3 = new String(charArray);
System.out.println(str1==str2); // true
System.out.println(str1==str3); // false
System.out.println(str2==str3); // false
}
}
字符串的比较相关方法
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:
public boolean eqeuals(Object obj):参数是一个字符串并且内容相同才会给true;否则返回false
注意事项:对象都能用Object进行接收
- 任何对象都能用Object进行接收
- equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样
- 如果比较双方一个常量一个变量,推荐常量写在前面,变量写在后面
package demo1;
public class t1 {
public static void main(String[] args) {
String str = null;
System.out.println("abc".equals(str)); //推荐:false
System.out.println(str.equals("abc")); //不推荐:报错-空指针异常NullPointExpection
}
}
package demo1;
public class t1 {
public static void main(String[] args) {
String str1 = "hell";
String str2 = "hell";
char[] charArray = {'h','e','l','l'};
String str3 = new String (charArray);
System.out.println(str1.equals(str2)); //true
System.out.println(str2.equals(str3)); //true
System.out.println(str3.equals("hell")); //true
}
}
public boolean equals IgnoreCase(String str):忽略大小写,进行内容比较
package demo1;
public class t1 {
public static void main(String[] args) {
String strA = "JAVA";
String strB = "java";
System.out.println(strA.equalsIgnoreCase(strB)); //true,忽略大小写
System.out.println(strA.equals(strB)); //false,严格区分大小写
}
}
字符串的获取相关方法
String当中与获取相关的常用方法有:
public int length():获取字符串当中含有的字符个数
public String concat(String str):将当前字符串和参数字符串拼接成为返回值新的字符串
public char charAt(int index):获取指定索引位置的单个字符
public int indexOf(String str):查找参数字符串当中首次出现的索引位置,如果没有返回-1
package demo1;
public class t1 {
public static void main(String[] args) {
//获取字符串长度
int length = "asadsd".length();
System.out.println("字符串长度"+length);
//拼接字符串
String str1 = "hello";
String str2 = "world";
String str3 = str1.concat(str2);
System.out.println(str3); // helloworld
// 获取指定索引位置的单个字符
char c = "hello".charAt(1);
System.out.println("在1号索引位置的是"+c); //e
//查找参数字符串在本来字符串当中出现的第一次索引位置
String original = "helloworld";
original.indexOf("llo"); // 2
}
}
字符串的截取方法
字符串的截取方法,有两种重载形式:
public String substring(int index):截取从参数位置一直带字符串末尾,返回新字符串
public String substring(int begin,int end):截取从behin开始,一直到end结束,中间的字符串
备注:[begin,end)左闭右开
package demo1;
public class t1 {
public static void main(String[] args) {
String str1 = "helloworld";
String str2 = str1.substring(5);
System.out.println(str2); //world
String str3 = str1.substring(4, 7);
System.out.println(str3); //owo
}
}
字符的转换相关方法
String当中与转换相关的常用方法有:
public char[ ] toCharArray:将当前字符串拆分成为字符数组作为返回值
public byte[ ] getBytes();获得当前字符串的字节数组
public String replace(CharSequence oldString,CharSequence newString):将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串
package demo1;
public class t1 {
public static void main(String[] args) {
// 转换成为字符数组
char[] chars = "hello".toCharArray();
System.out.println(chars[0]); //h
System.out.println(chars.length); // 5
//转换成为字节数组
byte[] bytes = "hello".getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]); //104 101 108 108 111
}
// 字符替换
String str1 = "how do you do?";
String str2 = str1.replace("o", "*");
System.out.println(str2); //h*w d* y*u d*?
}
}
字符串的分割方法
分割字符串的方法:
public String[ ] split(String regex):按照参数的规则,将字符串切分成为若干部分
注意事项:split参数其实是一个正则表达式
package demo1;
public class t1 {
public static void main(String[] args) {
String str1 = "aaa,bb,ccc";
String[] strArray = str1.split(",");
for (int i = 0; i < strArray.length; i++) {
System.out.println(strArray[i]); //aaa bb ccc
}
}
}
练习:定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串.按照[word1#word2#word3]
package demo1;
public class t1 {
public static void main(String[] args) {
int[] array = {1,2,3};
specialStr(array);
}
public static void specialStr(int[] intArray){
String str = "[";
for (int i = 0; i < intArray.length; i++) {
if (i ==intArray.length-1){
str += "word"+intArray[i]+"]";
}else{
str += "world"+intArray[i]+"#";
}
}
System.out.println(str);
}
}
练习二:键盘输入一个字符串,并且统计其中各种字符出现的次数.种类有:大写,小写字母,数字,其他
当char类型进行数学运算时会直接提升为int类型
package demo1;
import java.util.ArrayList;
import java.util.Scanner;
public class t1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String userInput = sc.next();
filte(userInput);
}
public static void filte(String userInput){
char[] chars = userInput.toCharArray();
int countUpper = 0; //大写字母
int countLower = 0; //小写字母
int countOther = 0; //其他字符
for (int i = 0; i < chars.length; i++) {
char aChar = chars[i];//当前单个字符
if ('A'<=aChar && aChar<='Z'){
countUpper++;
}
else if ('a'<=aChar && aChar<='z'){
countLower++;
}
else{
countOther++;
}
}
System.out.println("大写字母有"+countUpper);
System.out.println("小写字母有"+countLower);
System.out.println("其他字母有"+countOther);
}
}
静态static关键字概述
静态static关键字修饰成员
如果一个成员变量使用了static关键字,那么这个变量不在属于对象自己,而是属于所在的类.多个对象共享同一个类
static修饰变量的情况
创建一个Student类
package demo1;
public class Student {
private int id;
private String name;
private int age;
static String room;
private static int idCounter = 0;//学号计数器,每当new了一个新的对象的时候,计数器++
public Student() {
idCounter++;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id = ++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
主程序
package demo1;
import java.util.ArrayList;
import java.util.Scanner;
public class t1 {
public static void main(String[] args) {
Student one = new Student("郭靖", 19);
one.room = "101教室";
System.out.println("姓名"+one.getName()+"年龄"
+one.getAge()+"教室:"+one.room
+"学生id:"+one.getId());
Student two = new Student("黄蓉", 16);
System.out.println("姓名"+two.getName()+"年龄"
+two.getAge()+"教室:"+two.room
+"学生id:"+two.getId());
}
}
static修饰方法的情况
一旦使用static修饰成员方法,那么这就成为了静态方法.静态方法不属于对象,而是属于类的.
如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它
这里对类的方法修饰效果与python@preperty属性方法类似,属性方法的作用就是通过@property把一个方法变成一个静态属性
但是更加接近python的@staticmethod:静态方法类似,但是python静态方法是不可以访问实例变量或类变量的,它只是类下面的一个函数,跟类本身没关系,只是名义上归类管。
创建一个Myclass类
package demo1;
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(numStatic);
//访问成员
System.out.println(num); //报错,静态不能访问非静态
}
}
注意
- 静态不能直接方法非静态
- 原因:因为在内存中是先有的静态内容,后有的非静态内容,先人不知后人,但是后人只先人
- 静态方法不能用this,因为java的this就类似于python的self,都表示当前对象.静态方法自成一家,不用对象,属于类管辖.
package demo1;
public class t1 {
public static void main(String[] args) {
Myclass myclass = new Myclass(); //创建对象
//调用成员方法,没有static必须用对象调用
myclass.method();
//调用静态方法,直接通过类名称进行调用
Myclass.methodStatic();
//对于本类当中的静态方法,可以省略类名称
myMethod();
}
public static void myMethod(){
System.out.println("本类方法");
}
}
注意:
1.无论是成员变量,还是成员方法.只要有了static,都使用类名称进行调用
2.对于本类当中的静态方法,可以省略类名称
静态static的内存图
静态代码块
特点:
- 当第一次用到本类是,静态代码块执行唯一的一次
- 静态内容总是优先于非静态,索引静态代码块比构造方法先执行
静态代码块的用途:
用来一次性地对静态成员进行赋值
package demo1;
public class Person {
//静态代码块
static {
System.out.println();
}
}
Arrays一个与数组相关的工具类
Arrayts工具类:内部提供了大量的静态方法,用来实现数组的常见操作
public static String toString(数组):将数组变成字符串(默认格式[元素1,元素2,元素3])
package demo1;
import java.util.Arrays;
public class t1 {
public static void main(String[] args) {
int[] intArray = {1,2,30};
String intStr = Arrays.toString(intArray);
System.out.println(intStr); //[1,2,30]
}
}
public static void sort(数组):按照默认升序对数组的元素进行排序.
package demo1;
import java.util.Arrays;
public class t1 {
public static void main(String[] args) {
//数字进行排序
int[] array = {1,52,41,47};
Arrays.sort(array); //注意:原地修改
System.out.println(Arrays.toString(array));//[1,41,47,52]
//字符串进行排序
String[] array2 = {"sss","ccc","aaa"};
Arrays.sort(array2);
System.out.println(Arrays.toString(array2));
}
}
注意:
- 如果是数值,sort是默认升序
- 如果是字符串,sort默认按照字母升序
- 如果是自定义类型,name这个自定义类需要有Comparable或者Comoarator接口的支持
练习:将一个随机字符串中的所有字符升序排列,并倒叙打印
- 字符串转换为字符数组.toCharArray()
- 升序排序,工具类Arrays.sort方法
- 反向打印.fori是正序;.forr是倒叙
package demo1;
import java.util.Arrays;
import java.util.stream.IntStream;
public class t1 {
public static void main(String[] args) {
String str= "asdsddsfd";
char[] chars = str.toCharArray();
Arrays.sort(chars);
// chars.forr倒叙
for (int i = chars.length-1; i >=0; i--) {
System.out.print(chars[i]);
}
}
}
属性工具类Math
Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作
public static double abs(double num):获取绝对值
public static double ceil(double num):向上取整
public static double floor(double num):向下取整
public static long round(double num):四舍五入
package demo1;
import java.util.Arrays;
import java.util.stream.IntStream;
public class t1 {
public static void main(String[] args) {
//绝对值
System.out.println(Math.abs(-2.5)); //2.5
//向上取整
System.out.println(Math.ceil(3.9)); //4.0
//向下取整
System.out.println(Math.floor(4.5)); //4.0
//四舍五入
System.out.println(Math.round(4.4)); //4.0
System.out.println(Math.round(4.7)); //5.0
}
}
练习:计算-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?
package demo1;
public class t1 {
public static void main(String[] args) {
System.out.println(Math.floor((10.8-6)+(2.1*2)));
}
}