JDK API 1.8 中文版 jdk api 1.8.CHM
内置数据类型对应的包装类Number
一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包。
public class Test{public static void main(String args[]){Integer x = 5;x = x + 10;System.out.println(x);}}
当 x 被赋为整型值时,由于x是一个对象,所以编译器要对x进行装箱。然后,为了使x能进行加运算,所以要对x进行拆箱。
简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
(1)Java 会对 -128 ~ 127 的整数进行缓存,所以当定义两个变量初始化值位于 -128 ~ 127 之间时,两个变量使用了同一地址:
Integer a=123;Integer b=123;System.out.println(a==b); // 输出 trueSystem.out.println(a.equals(b)); // 输出 true//当两个 Integer 变量的数值超出 -128 ~ 127 范围时, 变量使用了不同地址:a=1230;b=1230;System.out.println(a==b); // 输出 falseSystem.out.println(a.equals(b)); // 输出 true
Java 中 int 和 Integer 的区别
1. int 是基本数据类型,int 变量存储的是数值。Integer 是引用类型,实际是一个对象,Integer 存储的是引用对象的地址。**
Integer i = new Integer(100);Integer j = new Integer(100);System.out.print(i == j); //false
因为 new 生成的是两个对象,其内存地址不同。
2.**int 和 Integer 所占内存比较:
Integer 对象会占用更多的内存。Integer 是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。
3. 非 new 生成的 Integer 变量与 new Integer() 生成的变量比较,结果为 false。
/*** 比较非new生成的Integer变量与new生成的Integer变量*/public class Test {public static void main(String[] args) {Integer i= new Integer(200);Integer j = 200;System.out.print(i == j);//输出:false}}
因为非 new 生成的 Integer 变量指向的是 java 常量池中的对象,而 new Integer() 生成的变量指向堆中新建的对象,两者在内存中的地址不同。所以输出为 false。
4. 两个非 new 生成的 Integer 对象进行比较,如果两个变量的值在区间 [-128,127]** 之间,比较结果为 true;否则,结果为 false。
/*** 比较两个非new生成的Integer变量*/public class Test {public static void main(String[] args) {Integer i1 = 127;Integer ji = 127;System.out.println(i1 == ji);//输出:trueInteger i2 = 128;Integer j2 = 128;System.out.println(i2 == j2);//输出:false}}
java 在编译 Integer i1 = 127 时,会翻译成 Integer i1 = Integer.valueOf(127)。
5.** Integer 变量(无论是否是 new 生成的)与 int 变量比较,只要两个变量的值是相等的,结果都为 true。
/*** 比较Integer变量与int变量*/public class Test {public static void main(String[] args) {Integer i1 = 200;Integer i2 = new Integer(200);int j = 200;System.out.println(i1 == j);//输出:trueSystem.out.println(i2 == j);//输出:true}}
包装类 Integer 变量在与基本数据类型 int 变量比较时,Integer 会自动拆包装为 int,然后进行比较,实际上就是两个 int 变量进行比较,值相等,所以为 true。
Math
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
常用函数
巧记对floor()和ceil()的概念理解:
1. floor直接取其含义,也就是“地板”,地板在脚下,即向下取整。
2. ceil是ceiling的缩写,也就是“天花板”,天花板在头顶上,即向上取整。
这里需要注意,floor()和ceil()的返回值都是double类型的数值。
round()的四舍五入也可以引入y轴来确定:
不管正数还是负数,四舍五入法要求,凡是.5的小数,都要向上取整。
因此,负数.5小数的四舍五入,只需直接取绝对值,再加上负号,就完成了。
随机数
除了Math.random()获取0~1之间的随机数, 还有 java.util.Random 类。
// 实例化随机数Random r = new Random();// 得到0-7之间的随机数int num = r.nextInt(8);// 如果想得到 0-8 之间的随机数int num = r.nextInt(9);// 如果想得到50-100之间的随机数int num = r.nextInt(51)+50;// 这个 51 = 100 - 50 + 1
java.util.Random 类
String
常用方法:
取出字符串中的一个字 charAt()
String message = "Hello Java";// 取出第一个字char str = message.charAt(0);
去除多余空格 trim()
- 查找字符串 indexOf()
- 字符串拼接 substring()
- 字符串开始和结束内容判断 startsWith / endsWith
```java
if(fileName.endsWith(“.doc”)){
}System.out.println("是word文档");
if(url.startsWith(“https”)){ System.out.println(“网址是安全的”); }
- 字符串替换 replaceAll()```javaString str = "Java是一种广泛使用的计算机编程语言,拥有跨平台、面向对象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。";String newStr = str.replaceAll("Java","Python");//前旧值,后新值
关于 为啥是不可改变的
String s = "Google";System.out.println("s = " + s);s = "Runoob";System.out.println("s = " + s);//输出结果Runoob
从结果上看是改变了,但为什么门说String对象是不可变的呢?
原因在于实例中的 s 只是一个 String 对象的引用,并不是对象本身,当执行 s = “Runoob”; 创建了一个新的对象 “Runoob”,而原来的 “Google” 还存在于内存中。
这里可以根据 jdk 的源码来分析。
字符串实际上就是一个 char 数组,并且内部就是封装了一个 char 数组。
并且这里 char 数组是被 final 修饰的:
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];
并且 String 中的所有的方法,都是对于 char 数组的改变,只要是对它的改变,方法内部都是返回一个新的 String 实例。
String 类的常见面试问题
面试题一:
String s1 = "abc"; // 常量池String s2 = new String("abc"); // 堆内存中System.out.println(s1==s2); // false两个对象的地址值不一样。System.out.println(s1.equals(s2)); // true
面试题二:
String s1="a"+"b"+"c";String s2="abc";System.out.println(s1==s2);System.out.println(s1.equals(s2));java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。
面试题三:
String s1="ab";String s2="abc";String s3=s1+"c";System.out.println(s3==s2); // falseSystem.out.println(s3.equals(s2)); // true
先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false。
Java String、StringBuffer 和 StringBuilder 的区别
String:字符串常量,字符串长度不可变。Java中String 是immutable(不可变)的。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。
StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。
StringBuilder:字符串变量(非线程安全)。在内部 StringBuilder 对象被当作是一个包含字符序列的变长数组。
基本原则:
- 如果要操作少量的数据用 String ;
- 单线程操作大量数据用StringBuilder ;
- 多线程操作大量数据,用StringBuffer。
众所周知,通过 new 关键字来生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的。因此通过 new 来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。
时间日期类
转化
日期时间——>字符串的转化:
import java.time.LocalDate;import java.time.format.DateTimeFormatter;public class DateTest5 {public static void main(String[] args) {LocalDate time = LocalDate.now();// 打印默认的时间数据System.out.println(time.toString());// 创建一个格式化方式DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd");// 或者利用SimpleDateFormat类// SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");// 执行时间的格式化处理,得到期望格式的时间字符串String timeStr = df.format(time);// 打印时间System.out.println(timeStr);}}
字符串——>日期时间:
import java.time.LocalDate;public class DateTest {public static void main(String[] args) {// 定义一个时间字符串,日期是2019年1月1日//默认格式yyyy-MM-ddString date = "2019-01-01";// 把字符串转化位 LocalDate 对象,并得到字符串匹配的日期LocalDate date2 = LocalDate.parse(date);// 打印出日期System.out.println(date2.toString());}}
自定义格式
import java.time.LocalDate;import java.time.format.DateTimeFormatter;public class DateTest {public static void main(String[] args) {// 定义一个时间字符串,日期是2019年1月1日String date = "2019/01/01";DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy/MM/dd");// 把字符串转化位 LocalDate 对象,并得到字符串匹配的日期LocalDate date2 = LocalDate.parse(date,df);// 打印出日期System.out.println(date2.toString());}}
获取日期时间具体的值:
import java.time.LocalDate;public class DateTest7 {public static void main(String[] args) {LocalDate time = LocalDate.now();// 得到当前时间所在年int year = time.getYear();System.out.println("当前年份 " + year);// 得到当前时间所在月int month = time.getMonth().getValue();System.out.println("当前月份 " + month);// 得到当前时间在这个月中的天数int day = time.getDayOfMonth();System.out.println("当前日 " + day);// 得到当前时间所在星期数int dayOfWeek = time.getDayOfWeek().getValue();System.out.println("当前星期 " + dayOfWeek);}}
这里有的用getValue()有的没有,点击拓展
日期比较
Java使用以下三种方法来比较两个日期:
- 使用 getTime() 方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
- 使用方法 before(),after() 和 equals()。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
- 使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。
