前言
现在,假定已经成功地安装了JDK,我们将开始介绍程序设计。本文主要介绍了程序设计的基本概念在Java中的实现方式。
一、字符串
1、创建字符串
//直接赋值法
String str = "Hello world!";
//通过new来创建字符串对象
String str = new String("Hello world!");
//通过char数组来创建字符串
char[] data = {'h','e','l','l','o'};
String str = new String(data);
注意:"hello world!"称为字符串字面量。字面量:直接写出来的值都被称为字面量。
2、 字符串的内存布局
String是一个引用数据类型,默认值为null。对象在堆上存储,引用在栈上存储。
String str = "hello";
String str1 = str;
3、字符串相等比较(重点)
字符串比较相等的值时使用equals方法,Java中每个类都有equals方法,它是Object自带的方法,所有类都继承Object类。equals的返回值是一个boolean值。
观察一下代码的输出:
int x = 10 ;
int y = 10 ;
System.out.println(x==y); //true
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1==str); // false
为什么两个字符串内容相同,而使用 == 得到的结果不同呢?来看内存图分析:
可知:== 本身是进行数值比较的,若用于对象比较,则比较的是两个对象所保存的内存地址是否相等,而并没有比较对象的内容。若想要进行内容比较,则必须采用String类提供的equals方法:
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1.equals(str));
思考:假设现在str由用户输入。要判断str内容是否为"hello",用哪一种写法更优?
//1
Str.equals("hello");
//2
"hello".equals(str);
答:选②。equals方法是通过对象调用的,是成员方法,必须有对象才可以使用。用户输入可能为null,此时①会产生空指针异常。
4、字符串的常量池(高效)
JVM会对字符串创建一个常量池。当使用直接赋值创建字符串时,字面量是第一次出现的话,JVM会创建一个字符串对象扔入常量池中。当字面量多次出现使用时,并不会创建新的对象,而是复用已有对象。故使用字符串时,最好使用直接赋值法,避免产生垃圾空间。
5、理解字符串的不可变性(重点)
String str = "hello";
str = "world";
此时只是str的指向发生了变化,指向了新的字符串world,而对于原字符串hello没有影响。由此可见会形成大量的垃圾空间。因此我们应该尽量避免在代码中用循环对字符变量的引用不断赋值。
一下代码可以体现出字符串的不可变性:
import java.util.Arrays;
public class StringCode {
static String str = "hello";
static char[] data = {'a','b','c'};
public static void main(String[] args) {
change(str,data);
System.out.println(str);
System.out.println(Arrays.toString(data));
}
private static void change(String str, char[] data) {
str = "world";
data[0] = 'g';
}
}
6、StringBulider类
当需要大量修改字符串内容时,我们常用StringBuilder类。
StringBuilder sb = new StringBuilder("hello");
sb.append(" worle");
sb.append("!!!");
String ret = sb.toString();
System.out.println(ret);
StringBuilder具备一些String类不具备的方法(扩展)
reverse();//反转
delete(int start,int end);//删除 左闭右开
insert(int start,char[] c);//插入
7、关于字符串的一些常规操作
方法名称 | 描述 |
---|---|
public boolean equals(Object anobject) | 区分大小写的比较 |
public boolean equalsIgnoreCase(String anotherString) | 不区分大小写的比较 |
public int compareTo(String anotherString) | 比较两个字符串大小关系 |
public boolean contains(CharSequence s) | 判断一个子字符串是否存在 |
public String replaceAll(String regex,String replacement) | 替换所有指定内容 |
public String replaceFirst(String regex,String replacement) | 替换首个内容 |
public String[] split(String regex) | 将字符串全部拆分 |
public String[] split(String regex,int limit) | 将字符串部分拆分,该数组长度就是limit极限 |
public String substring(int beginIndex) | 从指定索引截取到结尾 |
public String substring(int beginIndex,int endIndex) | 截取部分内容 |
public String trim() | 去掉字符串中的左右空格,保留中间空格 |
public String toUpperCase() | 字符串转大写 |
public String toLowerCase() | 字符串转小写 |
二、输入与输出
1、读取输入
前面已经看到,将输出打印到“标准输出流”是一件非常容易的事情,只要调用System.out.println即可。然而,读取“标准输入流”System.in就没这么容易了。要想通过控制台进行输入,首先需要构造一个与“标准输入流”System.in关联的Scanner对象。
Scanner in = new Scanner(System.in);
现在就可以使用Scanner类的各种方法读取输入了。例如,nextLine方法将读取一行输入。
String name = in.nextLine();
在这里,使用nextLine方法是因为在输入中可能包含空格。要想读取一个单词(以空白符作为分隔),可以调用
String firstName = in.next();
方法 | 用途 |
String nextLine() | 读取输入的下一行内容 |
String nex() | 读取输入的下一个单词(以空格作为分隔符) |
int nextInt() double nextDouble() | 读取并转换下一个表示整数或浮点数的字符序列 |
boolean hasNext() | 检测输入中是否还有其他单词 |
boolean hasNextInt() boolean hasNextDouble() | 检测是否还有下一个表示整数或者浮点数的字符序列 |
2、格式化输出
可以使用语句System.out.print(x);将x输出到控制台。例如:
double x = 10000.0/3.0;
System.out.print(x);
打印:3333.3333333333335;
如果希望显示美元、美分,这就会有问题。庆幸的是,Java5沿用了C语言函数库中的printf方法。例如,调用
System.out.printf(“%8.2f”,x);
会以个字段宽度打印x:这包括8个字符,另外精度为小数点后2个字符。也就是说,这会打印一个前导的空格和7个字符,如下:
3333.33
可以为printf提供多个参数,例如:
System.out.printf(“Hello, %s. Next year, you'll be %d”,name,age);
转换符 | 类型 | 示例 |
d | 十进制整数 | 159 |
x | 十六进制整数 | 9f |
o | 八进制整数 | 237 |
f | 定点浮点数 | 15.9 |
e | 指数浮点数 | 1.59e+01 |
g | 通用浮点数(e和f中较短的一个) | - |
a | 十六进制浮点数 | 0x1.fccdp3 |
s | 字符串 | Hello |
c | 字符 | H |
b | 布尔值 | true |
h | 散列码 | 42628b2 |
% | 百分号 | % |
n | 与平台有关的行分隔符 | - |