使用substring(int beginIndex,int endIndex)提取子串:
String greeting = "hello";
String subGreeting = greeting.substring(0,3);
>>hel
Java语言使用“+”拼接字符串,注意:当字符串与非字符串的值进行拼接时,后者会自动转为字符串
String greeting = "hello";
int length = 18;
System.out.print(greeting+length);
>>hello18
如果需要把多个字符串放在一起,用一个界定符分隔,可以使用静态join方法
String all = String.join("/","h","e","l");
>>h/e/l
String类中没有提供修改字符串中某一个字符的方法。如果需要修改某一个字符串,可以先提取该字符串的子串,然后再与希望替换的字符拼接
greeting = greeting.substring(0,3)+"p!";
>>help!
注意:上述修改的只是变量greeting的指向,其实“hello”字符串还是存在于内存中的,而“help!”是一个新创建的字符串。只是将原本指向hello的变量greeting重新指向了“help!”
可以使用equals方法检测两个字符串是否相等:
String str1 = "hello";
String str2 = "hello";
boolean b1 = str1.equals(str2);//这是对字符串变量进行比较
boolean b2 = "hello".equals(str2);//这是对字符串字面量进行比较
System.out.print(b1,b2);
>>true,true
使用equalsIgnoreCase方法对字符串进行不分大小写的比较
String str1 = "HELLO";
String str2 = "hello";
boolean b1 = str1.equalsIgnoreCase(str2);
System.out.print(b1);
>>true
注意:一定不要使用"==“比较字符串是否相等,因为”=="比较的是字符串是否在内存中相同的位置
如果虚拟机始终将相同的字符串共享,那么可以使用“==”检测是否相等。但实际上只有字符串字面量是共享的,而+或substring等操作得到的字符串是不共享的,例如:
String greeting = "hello";
if(greeting == "hello"){
System.out.print("yes");
}else{
System.out.print("no");
}
if(greeting.substring(0,3) == "hel"){
System.out.print("yes");
}else{
System.out.print("no");
}
>>yes
no
空串""是长度为0的字符串,它是一个Java对象,有自己的长度(0)和内容(空)。
Null串是String变量中的一个特殊值,名为null,表示没有任何对象与此关联。null串既无内容也无长度
String str1 = null;
String str2 = "";
System.out.println(str2.length());
System.out.print(str1.length());
>>0
Exception in thread "main" java.lang.NullPointerException at com.one.Demo07.main(Demo07.java:8)
有时需要由较短的字符串构建字符串,如果使用字符串拼接的方式,效率会很低。每次拼接字符串的时候都要一个新的String对象,既耗时又浪费空间。使用StringBuilder可以避免这种情况发生。
//首先构建一个空的字符串构造器
StringBuilder sBuilder = new StringBuilder();
//StringBuilder append(String str)追加一个字符串并返回this
sBuilder.append("abc");
//StringBuilder append(Char ch)追加一个字符串并返回this
sBuilder.append('2');
//toString得到一个String对象
String str = sBuilder.toString();
//在索引为2的位置插入一个字符串
sBuilder.insert(2, "hello");
sBuilder.insert(0, '9');
int len = sBuilder.length();
sBuilder.delete(len-2,len-1);
//获取StringBuilder的容量
int l = sBuilder.capacity();
System.out.printf("%d,%s",len,sBuilder);
扩展
StringBuffer、StringBuilder和String一样,也用来代表字符串。String类是不可变类,任何对String的改变都 会引发新的String对象的生成;StringBuffer和StringBuilder则是可变类,任何对它所指代的字符串的改变都不会产生新的对象。
###StringBuffer、StringBuilder区别
先说一下集合的故事,HashTable是线程安全的,很多方法都是synchronized方法,而==HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也是如此,他们的原理和操作基本相同,区别在于StringBufferd支持并发操作,线性安全的,适合多线程中使用==。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用。新引入的StringBuilder类不是线程安全的,由于StringBuffer使用了大量的同步函数所以在单线程中的性能比StringBuilder低。
所以,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer。
import java.util.*;
Scanner scanner = new Scanner(System.in);
//nextLine()方法将读取一行输入
String name = scanner.nextLine();
//next()方法读取一个单词,以空白符作为分隔符
String firstName = scanner.next();
//nextInt()读取一个整数
int age = scanner.nextInt();
//读取一个浮点数
double price = scanner.nextDouble();
格式化输出:
String name = "张三";
int age = 18;
System.out.printf("name:%s,age:%d",name,age);
如果 基本的整数和浮点数精度不能满足需要,可以使用java.math包中的类:BigInteger和BigDecimal。前者实现任意精度的整数运算,后者实现任意精度的浮点数运算。
//使用静态的valueOf方法可以将普通的数值转换为大数
BigInteger a = BigInteger.valueOf(100);
//对于更大的数,可以使用一个带字符串参数的构造器
BigInteger b = new BigInteger(123456789987654321123456789);
大数运算中不能使用“+”或“-”等算术运算符,而要使用add和multiply方法。
BigInteger c = a.add(b);
BigInteger d = c.mutiply(b.add(BigInteger.valueOf(2))); //d=c*(b+2)
基本数据类型计算公式与大数计算转换:
result = result * (n-i+1)/i;
result = result.muliply(BigInteger.valueOf(n-i+1)).divide(BigInteger.valueOf(i));
java.math.BigInteger API
API | 功能 |
---|---|
BigInteger add(BigInteger other) | 返回这个大数与另一个大数的和 |
BigInteger subtract(BigInteger other) | 差 |
BigInteger multiply(BigInteger other) | 积 |
BigInteger divide(BigInteger other) | 商 |
BigInteger mod(BigInteger other) | 余数 |
BigInteger sqrt() | 平方根 |
int compareTo(BigInteger other) | 相等返回0,大于other返回正数,否则返回负数 |
static BigInteger valueOf(long x) | 返回值等于x的大整数 |
java.math.BigDecimal API
API | 功能 |
---|---|
BigDecimal divide(BigDecimal other) | 商,若除不尽会抛出异常 |
BigDecimal divide(BigDecimal other,RoundingMode mode) | 商,若除不尽则四舍五入 |
static BigDecimal valueOf(long x, int scale) | 返回值等于x或x/10scale的一个大实数 |
其他同BigInteger |
int[] arrays = {1,2,3,4,5,6};
//使用普通for循环打印
for(int i = 0; i < arrays.length; i++){
System.out.print(arrays[i]);
}
//使用foreach
for(int j : arrays){
System.out.print(j);
}
//使用Arrays.toString(a)
System.out.print(Arrays.toString(arrays));
注意:for each的循环变量会循环遍历数组中的每个元素,而不是下标值
(1)将一个数组变量拷贝到另一个数组变量。这时,两个变量同时引用同一个数组:
import java.util.*;
int[] arrays1 = {1,2,3,4,5,6};
int[] arrays2 = arrays1;
arrays2[2] = 7;
System.out.println(arrays1[2]);
>>7
(2)将一个数组中的所有值 都拷贝到另一个数组中:
int[] array3 = Arrays.copyOf(arrays1, arrays1.length);
array3[0]=0;
System.out.println(arrays1[0]);
>>1
Arrays.copyOf()第二个参数是新数组 的长度,这个方法常用来增加数组 的大小:
int[] array3 = Arrays.copyOf(arrays1, 2*arrays1.length);
如果数组是数值型的,那么额外的元素将会被赋值为0;如果数组类型为布尔型,那么多余的会被赋值false。