文章目录
这部分内容主要靠自己练习。
一、API的定义和用处
我们在学习c语言的时候应该都用过sqrt()函数,它就位于标准库math.h中。像这种标准库都是c语言自带的,我们每次调用这个函数的时候,都只需引入头文件#include<math.h>即可。
java里肯定也有类似的东西(就是说我们没必要专门去写一个开平方根这样的函数,java人家本身就给我们提供了,需要的时候调用一下即可),把对程序员友好的一些函数封装成一个类,只不过这些类在java里不叫标准库,叫API。
API(Application Programming Interface):维基百科给的定义是应用程序接口。这种应用程序接口主要是给客户用的(开发人员也会用到)。
Java API:显而易见,就是给java开发人员用的API。换言之,Java API 就是给java开发人员提供的应用程序编程的接口,方便程序员去开发。
一般来说,只要有API(不管是java API、C# API、c标准库,还是其它开源项目的API),就应当有对应的API 文档(文档一般是公开的)。java8 API 文档
只要我们把API文档研究透了,只要我们把源码研究透了,我们就知道java底层是怎么实现的,我们也就知道那些所谓的高级功能,其实只不过就是java文档里的东西而已。API文档越熟悉,就会对java理解地稍微越深入(不过有的东西API文档里没有)。
API、jar包、jdk之间的关系
问题起源:查看某个方法的文档时,发现java.lang这个库在jdk的目录下。
关系:java自带的一些API和文档封装在一些类库里,这些类组织在jar包里,这些基础的jar包java开发程序中最基础的部分,几乎所有的java程序都依赖它们,因此,它们是jdk(jdk是java的开发工具包,里面主要包括了java编译器(javac)、java运行时(jre)、以及用于开发的各种工具(如调试器、文档生成器等))的一部分。当然,jdk的标准库虽然非常强大,但它并不包括所有功能(例如:数据库连接、网络编程等),此时就需要第三方库(第三方库以jar包形式提供,其中包含了库的实现代码以及API文档)的支持,这就是为什么有些项目会额外引入jar包。
二、Scanner
package com.practice.demo;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 从键盘接收数据
Scanner scan = new Scanner(System.in);
System.out.println("next方式接收数据: ");
/* hasNext()是Scanner里的一个方法,
目的在于判断用户究竟有没有输入数据,
如果没有输入, 直接把这个scan关闭,
使代码更加严谨
*/
if(scan.hasNext()){
String str1 = scan.next();
System.out.println("输入的数据是: " + str1);
}
// scan.close();
Scanner scan1 = new Scanner(System.in);
System.out.println("nextLine方式接收数据: ");
if(scan1.hasNext()){
String str2 = scan1.nextLine();
System.out.println("输入的数据是: " + str2);
}
scan1.close();
}
}
运行上述代码,就可以看出next()和nextLine()的区别。next()读取字符串时遇到空格就会停止,nextLine()不会。
能读取字符串,就可能能读取整数。可能会换一个方法名(这里就是),也可能会用到重载。其余同理。
遇到看不懂的东西时,可以直接Ctrl + 左键单击 查看源码(不要乱改jdk自带的这些代码,否则就会破坏jdk源码)注释。如果看不懂英文,就把这段英文翻译粘到翻译软件里看中文(直接看中文文档也行)。实在不行就把这个方法名粘到浏览器里看看有没有相关博客。
例如:当我们想知道nextInt()和nextInt(int radix)的区别时,就可以直接去看它们的源码。不行的话就直接把public int nextInt(int radix)粘到浏览器里,看看有没有相关博客。
小工具(ZoomIt)
三、Number
1. 包装类
概念:包装类是利用用面向对象的思想,对java中的基本数据类型(如int、double等)进行封装的类。这种封装使得基本数据类型能够以对象的形式存在和操作。
好处:① 面向对象操作:通过包装类,我们可以像操作对象一样操作基本数据类型。这意味着可以调用包装类提供的方法,实现继承等面向对象的特性。② 方法和状态的添加:包装类可以拥有方法和状态,这为基本数据类型带来了更多功能。例如,集合存储:由于集合(如List、Set等)只能存储对象,包装类允许我们将基本数据类型的值存储在集合中。例如,可以创建一个List来存储一系列的int值;类型转换:包装类提供了类型转换的方法,如Integer.parseInt,它可以将字符串转换为对应的整数。
package com.practice.demo;
public class Main {
public static void main(String[] args) {
// 自动装箱:将基本数据类型int转换为Integer对象
Integer intObj = 10;
// 调用Integer类的方法
int hexValue = intObj.parseInt("A", 16); // 将十六进制字符串"A"转换为十进制整数
System.out.println("十六进制的'A'对应的十进制数值是: " + hexValue);
// 使用Integer类的静态方法valueOf转换为Integer对象,然后调用方法
Integer intObj2 = Integer.valueOf(20);
boolean isLess = intObj.compareTo(intObj2) < 0; // 比较两个Integer对象
System.out.println("intObj < intObj2: " + isLess);
// 实现继承的例子
// 假设我们有一个自定义的类继承自Number
class MyNumber extends Number {
private Integer value;
public MyNumber(Integer value) {
this.value = value;
}
@Override
public int intValue() {
return value;
}
@Override
public long longValue() {
return value.longValue();
}
@Override
public float floatValue() {
return value.floatValue();
}
@Override
public double doubleValue() {
return value.doubleValue();
}
}
// 使用自定义的类
MyNumber myNumber = new MyNumber(30);
System.out.println("MyNumber对象的值: " + myNumber.intValue());
}
}
补充:Ctrl + 左键单击 Integer会出现文档;Ctrl + 左键单击 int没有反应。输入x. 后面会显示一些方法名;输入y.后面显示的是idea的一些快捷输入方式。因为Integer是一个类,而int只是一个基础的数据类型。
2. Number类
所有数值类型的包装类(如:Ingeter等)都是抽象类Number的子类。换言之,Number类为所有数值类型的包装类提供了一个公共的超类。
作用:① 管理和定义数值类型的类:Number类为所有数值类型的包装类(如Integer、Double、Float、Long、Byte、Short)提供了一个公共的接口和部分实现,这样所有的数值包装类都可以继承Number类的方法和属性。② 提供转换方法:Number类定义了一系列的方法,如intValue(), doubleValue(), floatValue(), longValue(), byteValue(), 和 shortValue(),这些方法允许其子类(即具体的数值包装类)提供将包装类对象转换为对应的基本数据类型值的功能。
Integer intObj = 10; // 自动装箱
int intVal = intObj.intValue(); // 使用intValue()方法转换为基本数据类型int
3. 自动装箱和自动拆箱
自动装箱:将基本数据类型自动转换成对应的包装类对象。通俗来讲就是,Java帮你把基本数据类型“打包”成一个对象,放进了一个虚拟的“大箱子”里。
自动拆箱:当需要基本数据类型进行算数运算或赋值给基本数据类型变量时,将包装类对象转换回基本数据类型。通俗来讲就是,Java在你需要用到基本数据类型时,自动把这个对象从“大箱子”里“拆开”,让你可以直接使用里面的基本数据类型值。
// 自动装箱
Integer x = 5;
// 先拆箱,后装箱
x = x + 10;
System.out.println(x);
4. 书籍
四、Math
菜鸟教程
①
我们可以发现,Math里的方法全定义成了static,好处在于:可以直接"类名."使用,没有必要再new一个对象(例如:System.out.println(“90 度的正弦值:” + Math.sin(Math.PI/2)); )
我们以后写工具类的时候,也可以把这个工具类里的方法定义成static。
② java源码的max方法中,出于严谨,比较浮点数时会加一些判断。
五、Random
1. 在哪找
Math里面有一个random方法,可以用来生成0到1直接的随机数。Ctrl + 左键单击 random,查看源码。
Ctrl + 左键单击 randomNumberGenerator,发现还有一个Random类。
这个Random类在java.util包里。
Random类:jdk 9 docs
隶属模块:java.base
隶属包:java.util
父类:java.lang.Object
实现哪个接口:Serializable
子类:SecureRandom, ThreadLocalRandom
种子(seed):不传种子的时候,用的是当前的时间戳
随机数生成算法
2. 作用
① Random类:专门用来处理随机数。Math.random只能生成0到1的随机数,但是不能对生成的数据加以限制,Random类里的方法可以。
② bound:界。限定最大值(不包括这个最大值)
③ 缺点:只能限定int类型随机数的最大值,而且没有办法限定随机数的起始值(当然也可以自己手动补充代码,实现相应效果,只不过比较麻烦)。
3. ThreadLocalRandom
ThreadLocalRandom是Random的子类。调用这个类里的方法可以对生成的随机数范围加以限制。文档
用的时候记得调用静态方法current> ThreadLocalRandom本身就是给并发的情况使用的,据测试,如果有1000条数据,使用Random大概有600-700微秒,用ThreadLocalRandom只要500多微秒。如果数据超级多,可能消耗时间差异会更明显。
六、Date
1. Date
① 时间戳、Unix时间、2038年问题
② 通讯录第一个创建者 – 微软(维基百科词条:Windows联络人)
但是上世纪的时候它的性能不太好,容易卡(因为要进行abcd这种按姓名排列,还要进行插入删除等操作,如果用链表,那就会很麻烦),这个问题后来被一个实习生解决了。
③ Date类在java.util包里 jdk 9 docs
④ Deprecated 已过时
⑤ 查看当前时间戳
⑥ 为什么要×1000
⑦ compareTo用法
package com.practice.demo;
import java.util.Date;
public class Main {
public static void main(String[] args) {
/* 不常用(返回系统当前时间)
输出时自动调用toString方法
*/
Date date = new Date();
System.out.println(date);
/* 常用(返回系统当前时间)
输出时自动调用toString方法
*/
System.out.println(new Date());
// 返回该时间戳对应的Unix时间
System.out.println(new Date(1999999L));
// 获取当前时间的时间戳, 单位:毫秒
System.out.println(new Date().getTime());
// 将时间戳转换成当前时间
System.out.println(new Date(1731722641523L));
// 需要×1000, 否则返回1970年的时间
// 下面的时间戳(单位: 秒)是网站上搜索的
System.out.println(new Date(1731723172L * 1000));
}
}
2. DateFormate和SimpleDateFormate
① DateFormate类属于java.text包,是Format类的子类。
② java.text包里有个Format类,专门用来格式化信息(例如:将字符串转换成想要的日期格式、将给定格式的日期转换成字符串)。
③ DateFormate是一个抽象类(例如:猫狗继承自动物类,这里的动物类就是抽象类。我们可以说让狗吃骨头、让猫吃鱼,但是不能说让动物吃骨头、让动物吃鱼),我们没办法new一个抽象类并将其作为对象使用,我们只能使用它的子类SimpleDateFormate。
④ 可以根据下面内容按需求定制输出格式
⑤ 点击上方的Add exception to method signature即可
package com.practice.demo;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
/* SimpleDateFormat(String pattern)最常用。
pattern意为按照格式、规则去输出
*/
// 按格式输出一个Date类型的数据
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
System.out.println(dateFormat.format(date));
// 把String类型数据转换成Date类型数据
DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
String nowTime = "2024-11-16 10-59-08";
Date date1 = dateFormat1.parse(nowTime);
System.out.println(date1);
}
}
3. Calendar
① Calendar类在java.util包里。jdk 9 docs
② Calendar类是一个抽象类,不能直接new,但是它提供了getInstance方法(static 单例模式)。
③ 西方国家定义程序的时候,月份是从0开始的(只有月份是这样),0代表是1月份。星期是从星期天开始的,即周日是第一天。
package com.practice.demo;
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
// 获取时间
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int month1 = calendar.get(Calendar.MONTH) + 1;
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);
System.out.println(year);
System.out.println(month);
System.out.println(month1);
System.out.println(dayOfMonth);
System.out.println(dayOfWeek);
System.out.println(hourOfDay);
// 设置时间, 返回一个日期对象
// 分钟等没有设置的会自动截取当前时间的信息
calendar.set(2099,12,1);
System.out.println(calendar);
// 输出当前年份(上面没注释的话用的是上面设置过的2099年)+8后的年份
calendar.add(Calendar.YEAR, 8);
System.out.println(calendar);
// 只获取年份
System.out.println(calendar.get(Calendar.YEAR));
}
}
4. System
① System类在java.lang包里。与时间戳有关。jdk 9 docs
② 里面的方法都是静态的,因此也不用new对象,直接就能用
package com.practice.demo;
public class Main {
public static void main(String[] args) {
// 获取当前时间戳
System.out.println(System.currentTimeMillis());
//系统级别的, 性能比array里的copy高
int[] src = {1, 2, 3, 4};
int[] dest = new int[5];
System.arraycopy(src, 0, dest, 1, 4);
for (int element:dest) {
System.out.println(element);
}
// 返回系统定时器的当前值,以纳秒为单位
System.out.println(System.nanoTime());
// 垃圾回收
System.gc();
// 终止当前运行的 Java 虚拟机
System.exit(0);
// 终止虚拟机后, 不会输出hh
System.out.println("hh");
//后续学框架会用getProperties方法
}
}
七、其它
可以用面向对象思想去理解数据结构