API帮助文档在day10
java学习上部
执行顺序:只执行main对象里面的代码,当有调用时才跳出去执行
循环控制:break结束整个循环,continue跳过本次循环执行下一个循环,遇到return即使后面有代码也不执行,在循环里面的定义不能拿到循环外使用
20231026:开始数组
关于方法:不能再一个方法中定义其他方法,只能在大环境下定义,可以在其他方法内部调用
方法已学完,开始综合练习视频
2023/10/30:
For()中可以不用i++,例如for(int n=0 ; n<5 ;)
Shift+f6可以批量修改变量名
Ctrl+alt+m可以抽取方法
2023/10/31:
面向对象,用来描述一类事物的类叫javabean类,这个类中是不写main方法的;编写main方法的叫做测试类,在这个类里面是创建类对象并赋值调用。一个java文件里只能有一个public修饰的类,可以定义多个类,但public类名要和文件名一样,建议实际开发时一个java文件定义一个类。
Private定义一个私有变量,在只能在此类中调用,在其他类中无法直接使用。
类里面的构造方法,!!!!构造方法没有返回值,甚至void都不能写,在创建对象的时候就自动调用
public Studentmethod(){
System.out.println("my name is"+name);
}//无参构造方法,如果代码不写构造方法,系统会自动给一个默认的没有功能的无参构造,一旦人为写了构造方法,虚拟机将不会自动提供
public Studentmethod(int age){
this.age=age;
}//有参数的构造方法,可以和无参构造同时存在,起到方法重载,在创建对象的时候需要传入参数
标准javabean写法:
成员变量私有化,无参和带全部参数的构造方法,每个成员变量对应set以及get方法
已经完成面向对象的基础知识
2023/11/1
创建存放类对象的矩阵
printf
占位输出,且没有换行功能
//!!!!注意两套体系不能混用
//体系一
// Scanner s=new Scanner(System.in);
// int sc=s.nextInt();//只能输入整数
// String k=s.next();//字符串
// Double kk=s.nextDouble();//输入double型
//对于体系一,不能在输入中有回车,空格,制表符,这些不能被接收,例如使用了空格,空格后的部分(包含空格)会被顺位到第二个接收变量
//体系二
for (int i = 0; i <arr.length ; i++) {
Goods c=new Goods();//不能放在循环外面,如果在循环外面相当于是一直在修改同一个地址的信息
//在这一步相当于反复新建类对象,地址是肯定会变的,类比于int a不同值,循环存入一个矩阵
System.out.println(c);
System.out.println("请输入id");
String id=s.next();
c.setId(id);
arr[i]=c;
2023/11/2
字符串不是基本数据类型,不是存储在栈空间
可以看到在调用System.out.println()方法的时候,println()方法首先是调用String类中的valueOf()方法来将传进来的对象转成String类型。所以在栈中,保存的是地址,但是print出来自动调用了方法,使得其变为了字符串
这样的方法创建的字符串会先观察串池里面有无,没有就创建,有就复用其地址
这种方法创建的不会在串池创建,在堆中,且不会复用地址
输入字符串是new出来的地址在堆里面
数组的length是属性,字符串的是方法,要加括号
char类型变量在参与计算或比较时会自动变为int
字符串截取其中的片段返回,不改变原来的数据
2023/11/06
Java允许链式编程
Java允许链式编程
2023/11/7
char[] a=s.toCharArray();
字符串转字符数组
2023/11/14
集合
集合自动伸缩
关于变量默认值
在java中,局部变量是没有默认值的,所以在声明时,如果没有赋值,后面程序直接使用该变量,编译器会检查出错误。(包装类也是如此)。而成员变量作为类的成员(基本数据类型),JVM会自动给他们赋初值。
引用类型初始化后未赋值之前的值为null
static 变量
如果在类中有这种变量,那么在实例化对象之前类名点变量名复制,此后所有的实例化类的该变量都是这个值,相当于是类中的公共变量
static 方法
工具类中方法定义为静态方便调用
在类方法中其实是省略了student this这个参数的,不能我们赋值,是虚拟机自动赋值
谁调用它,this反应的就是哪个对象的地址,若在这个方法中变量加上this.,则代表实例化一个类后,通过这个类的地址找到这个类地址中的变量
由于静态是共有的,所以如果在静态中去调用非静态,就不知道调用哪一个,在非静态中调用静态可以这么理解,如上图,this相当于就是在main方法中这个类的地址,静态又有两种调用方法,一是直接类名加点,二是实例化之后加点调用,所以this.method相当于是主函数中的s1.method,同理变量也是这个道理;如果构造方法私有化之后就只能类名.方法
继承
概述
多继承即继承多个父类
私有公有
package static_learning;
public class tes {
private void s(){
System.out.println("我是私有");
}
public void ss(){
s();
}
}
tes a=new tes();
a.ss();
s是私有,只能子类中调用,但实例化后调用ss则可以间接调用s
此处的访问不是继承
成员变量都能继承,但是只有非私有才能再main中直接调用
假如可以继承构造方法,那么类名就和构造方法名不一致,所以当继承时,构造方法继承不过去,但代码不报错,因为继承了其他可以继承的属性
堆空间的地址中会划分两个子区域,一边放父类变量,一边放子类变量,父类私有化变量不能再main中直接调用
继承方法
只有父类中的虚方法才能被子类继承
继承中成员变量的访问特点
就近原则,谁近用谁
先找局部,再找本类,再找父类
成员方法访问特点
package static_learning;
public class 方法重写 {
public static void main(String[] args) {
stu ss = new stu();
}
}
class Person {
int age;
String name;
public Person() {
System.out.println("父类的无参构造");
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}
class stu extends Person {
String id;
public stu() {
super();
System.out.println("子类的无参构造");
}
public stu(String id) {
super();
this.id = id;
}
}
父类的无参构造
子类的无参构造
package static_learning;
public class 方法重写 {
public static void main(String[] args) {
stu ss = new stu(12,"lll","123456");
System.out.println(ss.age+" "+ss.name+" "+ss.id);
}
}
class Person {
int age;
String name;
public Person() {
System.out.println("父类的无参构造");
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}
class stu extends Person {
String id;
public stu() {
super();
System.out.println("子类的无参构造");
}
public stu(int age,String name,String id) {
super(age,name);
this.id = id;
}
}
12 lll 123456
调用空参构造时,school有默认值
多态
多态成员变量的调用
左边是Animal所以是使用Animal中的变量
成员变量的调用
多态new的时候是根据new后面的类在堆空间创建一个小空间,和普通实例化一样,有自己的变量也有父类变量
缺点:
调用方法时如果子类在父类基础上添加了新方法,那么在多态中就无法调用。
解决方法:类型转换
Person a=new Student();
//student有一个特有的方法say2,直接用a调用不了,需要强转
Student d=(Student)a;
d.say2();//注意强转时a不能转为teacher类,即使teacher类中有这个方法也会报错,因为是person的student实例
//在强转时防止转错可以加上判断
if(a instanceof Student d){//判断a是否为student的实例,如果是则返回ture,并将a强转为d,不是则直接false
d.say2();
} else if (a instanceof Teacher d) {
d.say();
}
自动类型转换是指小范围的参给大范围的,就如student类给person类一样
多态调用成员变量
多态调用成员方法
包和final
包需要导包
权限修饰符和代码块
局部代码块,a所属的{}是一个代码块,用完就释放内存,后面就不能打印了
打印语句重复,可以写在构造代码块中
其实是写在成员位置的代码块,优先于构造方法执行,也渐渐淘汰了,不够灵活
若有的构造方法不用执行该语句可以这样做:1、写在一个构造方法中,其他构造需要就调用。2、包装成一个方法,需要的构造方法就调用该方法
静态代码块
在类加载的时候,做一些数据初始化的时候使用。就是在构造代码块基础上前面加上static
例如在执行文件时,会有个初始化的信息,先执行静态代码块再执行main方法,再上面代码中,list必须要被定义为静态。相当于全局变量
如果写在main方法中的话,main方法是可以被调用的,一旦调用就会每一次都创建这个list。
package 多态;
public class test {
public static int s=10;
static String a="qwe";
static {
a=a+"2";
}
public static void main(String[] args) {//这个是静态方法,无法使用外部的非静态
System.out.println(s);//10
System.out.println(test.s);//10
System.out.println(a);//qwe2
}
}
抽象类和抽象方法
定义格式
抽象方法不加{},直接;
抽象类虽然不能实例化,但如果里面有static方法,可以直接类名点方法名调用
抽象类有构造方法其实是可以由子类继承使用,在子类中需要重新所有抽象方法,点击子类类名红色波浪线alt+回车
子类也是抽象类
接口
接口就相当于一种规则,需要的时候调用,是对行为的抽象,而类是对事物的抽象
接口里面写抽象方法
实际演练
package 接口;
public abstract class animal {
String name;
int age;
public animal(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
public abstract void eat();//抽象方法
}
选择interface才是接口
package 接口;
public interface swim {//定义接口
public abstract void Swim();
}
package 接口;
public class frog extends animal implements swim {//在继承父类的同时,添加了接口
public frog() {
}
public frog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("青蛙在吃虫子");
}
@Override
public void Swim() {
System.out.println("青蛙在游泳");
}
}
package 接口;
public class cat extends animal {//猫没有游泳的能力,所以不添加接口
public cat() {
}
public cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫在吃老鼠");
}
}
package 接口;
public class 接口实现 {
public static void main(String[] args) {
frog f=new frog("青蛙1",1);
f.eat();
f.Swim();
cat c=new cat();
c.eat();
}
}
D:\Java\bin\java.exe "-javaagent:D:\javaIDE\IntelliJ IDEA 2023.2.3\lib\idea_rt.jar=56323:D:\javaIDE\IntelliJ IDEA 2023.2.3\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath D:\basic-code\basic-code\out\production\basic-code 接口.接口实现
青蛙在吃虫子
青蛙在游泳
猫在吃老鼠
Process finished with exit code 0
接口的细节
直接写int a=10;运行时会默认加上修饰符
如果实现类实现的多个接口中有重名方法,只需要重新一次就行,且两个接口的方法都被写成一样的了
接口多继承
注意:
在多继承时,实现类实现了最下层的子类接口,那么需要把子类及子类以前的抽象方法都重写
接口扩展内容
不能在实现类中被重写,但是允许实现类中有同名的方法
package 接口;
public interface swim {//定义接口
public abstract void Swim();
public static void s(){
System.out.println("s");
}
public default void ss(){
System.out.println("ss");
}
}
package 接口;
public class 接口实现 {
public static void main(String[] args) {
frog f=new frog("青蛙1",1);
f.eat();
f.Swim();
cat c=new cat();
c.eat();
swim.s();//静态方法只能被接口调用
f.ss();//default方法只能被实现类调用
}
}
总结来说,静态方法不能被类传给类,不能被接口传给实现类,只能用写它的类或接口点方法名调用
接口的应用
接口的多态
适配器设计模式
内部类
匿名内部类
紫色圈中的是没有名字的类,它实现了Swim接口,new()也是创建了紫色圈中的类
如果是继承类的情况:
如何使用
new animal(){};就已经相当于一个对象了,直接传入就行
项目细节
动作监听只能察觉到鼠标按下动作
常用API
math
System.out.println(Math.sqrt(4));//开平方
System.out.println(Math.cbrt(8));//开立方
system
细节点
runtime
object
重写后的tostring就可以直接打印内容,而不是地址,object里的tostring就是打印地址
对象克隆
如果不重写克隆方法,那么由于protected的限制,只能在不同类中子类中内部使用,而不能在不同包无关类里调用
package 常用API;
public class 使用Objects {
public static void main(String[] args) throws CloneNotSupportedException {
user s1=new user("ss",11);
user s2=new user("ss",11);
Object w=s1.cc();
System.out.println(s1.name+s1.age);
}
}
class user implements Cloneable{
String name;
int age;
public user(String name, int age) {
this.name = name;
this.age = age;
}
public user() {
}
public Object cc() throws CloneNotSupportedException {
Object k = this.clone();
return k;
}
这样就是在类中调用继承的方法
object中克隆是浅克隆
第三方是深克隆
Objects
biginteger
BigInteger b=new BigInteger(4,new Random());//获取随机的一个大整数
System.out.println(b);
BigInteger b1=new BigInteger("1245");//字符串内部只能是整数
System.out.println(b1);
//获取指定进制最大整数,字符串必须要为整数,将字符串转为相应进制
BigInteger b2=new BigInteger("12457",8);
System.out.println(b2);
不会创建新对象,只是返回大的值的地址
也可以.longvalue
bigdecimal
常规类型计算的不精确性
在进行运算时,是创建一个新的对象,而不会改变原有对象
除法如果除得尽可以只用第一个参数,除不尽就要写保留小数点后几位,以及舍入模式
half——up是四舍五入
转义字符
正则表达式
表达式是依照字符串从左到右一个一个去匹配的
X代表对象字符
此时只忽略b的大小写
爬虫
package com.itheima.a08regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo6 {
public static void main(String[] args) {
/* 有如下文本,请按照要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
要求:找出里面所有的JavaXX
*/
String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.获取正则表达式的对象
Pattern p = Pattern.compile("Java\\d{0,2}");
//2.获取文本匹配器的对象
//拿着m去读取str,找符合p规则的子串
Matcher m = p.matcher(str);
//3.利用循环获取
while (m.find()) {
String s = m.group();
System.out.println(s);
}
}
private static void method1(String str) {
//Pattern:表示正则表达式
//Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
// 在大串中去找符合匹配规则的子串。
//获取正则表达式的对象
Pattern p = Pattern.compile("Java\\d{0,2}");
//获取文本匹配器的对象
//m:文本匹配器的对象
//str:大串
//p:规则
//m要在str中找符合p规则的小串
Matcher m = p.matcher(str);
//拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
//如果没有,方法返回false
//如果有,返回true。在底层记录子串的起始索引和结束索引+1
// 0,4
boolean b = m.find();
//方法底层会根据find方法记录的索引进行字符串的截取
// substring(起始索引,结束索引);包头不包尾
// (0,4)但是不包含4索引
// 会把截取的小串进行返回。
String s1 = m.group();
System.out.println(s1);
//第二次在调用find的时候,会继续读取后面的内容
//读取到第二个满足要求的子串,方法会继续返回true
//并把第二个子串的起始索引和结束索引+1,进行记录
b = m.find();
//第二次调用group方法的时候,会根据find方法记录的索引再次截取子串
String s2 = m.group();
System.out.println(s2);
}
}
练习2
package com.itheima.a08regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo8 {
public static void main(String[] args) {
/*
需求:把下面文本中的座机电话,邮箱,手机号,热线都爬取出来。
来黑马程序员学习Java,
手机号:18512516758,18512508907或者联系邮箱:boniu@itcast.cn,
座机电话:01036517895,010-98951256邮箱:bozai@itcast.cn,
热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090
手机号的正则表达式:1[3-9]\d{9}
邮箱的正则表达式:\w+@[\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2}座机电话的正则表达式:θ\d{2,3}-?[1-9]\d{4,9}
热线电话的正则表达式:400-?[1-9]\\d{2}-?[1-9]\\d{3}
*/
String s = "来黑马程序员学习Java," +
"电话:18512516758,18512508907" + "或者联系邮箱:boniu@itcast.cn," +
"座机电话:01036517895,010-98951256" + "邮箱:bozai@itcast.cn," +
"热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";
System.out.println("400-618-9090");
String regex = "(1[3-9]\\d{9})|(\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})" +
"|(0\\d{2,3}-?[1-9]\\d{4,9})" +
"(400-?[1-9]\\d{2}-?[1-9]\\d{3})";
//1.获取正则表达式的对象
Pattern p = Pattern.compile(regex);
//2.获取文本匹配器的对象
//利用m去读取s,会按照p的规则找里面的小串
Matcher m = p.matcher(s);
//3.利用循环获取每一个数据 while(m.find()){
String str = m.group();
System.out.println(str);
}
}
package com.itheima.a08regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo9 {
public static void main(String[] args) {
/*
有如下文本,按要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
需求1:爬取版本号为8,11.17的Java文本,但是只要Java,不显示版本号。
需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8 Java11 Java17 Java17
需求3:爬取除了版本号为8,11.17的Java文本,
*/
String s = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
//1.定义正则表达式
//?理解为前面的数据Java
//=表示在Java后面要跟随的数据
//但是在获取的时候,只获取前半部分
//需求1:
String regex1 = "((?i)Java)(?=8|11|17)";
//需求2:
String regex2 = "((?i)Java)(8|11|17)";
String regex3 = "((?i)Java)(?:8|11|17)";//这个问号加冒号相当于获取全部
//需求3:
String regex4 = "((?i)Java)(?!8|11|17)";
Pattern p = Pattern.compile(regex4);
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
}
}
贪婪爬取:在爬取数据时尽可能多的爬取数据;非贪婪则相反
package com.itheima.a08regexdemo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo10 {
public static void main(String[] args) {
/*
只写+和*表示贪婪匹配
+? 非贪婪匹配
*? 非贪婪匹配
贪婪爬取:在爬取数据的时候尽可能的多获取数据
非贪婪爬取:在爬取数据的时候尽可能的少获取数据
ab+:
贪婪爬取:abbbbbbbbbbbb
非贪婪爬取:ab
*/
String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +
"经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +
"下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
String regex = "ab+";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
}
}
ctrl+alt+v可以自动生成等号左边的内容
String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";
String rex="[\\w&&[^_]]+";
String f = s.replaceAll(rex, "与");
System.out.println(f);
String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";
String rex="[\\w&&[^_]]+";
String f = s.replaceAll(rex, "与");//rex也可换成一个字符串,这样就能指定替代
String f2 = s.replaceAll("dq", "与");
System.out.println(f);
String[] arr = s.split("[\\w&&[^_]]+");//可以用正则表达式,也可以直接按里面的元素切割,其实是一个意思
String[] arr2 = s.split("dq");
捕获分组
//需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
//举例: abc123abc b456b 123789123 &!@abc&!@ abc123abd(false)
String regex2 = "(.+).+\\1";
System.out.println("abc123abc".matches(regex2));
//需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
//举例: aaa123aaa bbb456bbb 111789111 &&abc&&
//(.):把首字母看做一组
// \\2:把首字母拿出来再次使用
// *:作用于\\2,表示后面重复的内容出现日次或多次
String regex3 = "((.)\\2*).+\\1";
System.out.println("aaa123aaa".matches(regex3));
package com.itheima.a08regexdemo;
public class RegexDemo13 {
public static void main(String[] args) {
/*需求:
将字符串:我要学学编编编编程程程程程程替换为:我要学编程
*/
String str = "我要学学编编编编程程程程程程";
//需求:把重复的内容 替换为 单个的
//学学 学
//编编编编 编
//程程程程程程 程
// (.)表示把重复内容的第一个字符看做一组
// \\1表示第一字符再次出现
// + 至少一次
// $1 表示把正则表达式中第一组的内容,再拿出来用
String result = str.replaceAll("(.)\\1+", "$1");
System.out.println(result);
}
}
package com.itheima.a08regexdemo;
public class RegexDemo14 {
public static void main(String[] args) {
/*
非捕获分组:分组之后不需要再用本组数据,仅仅是把数据括起来。
身份证号码:
41080119930228457x51080119760902230915040119810705387X130133197204039024430102197606046442
*/
//身份证号码的简易正则表达式
//非捕获分组:仅仅是把数据括起来//特点:不占用组号
//这里\\1报错原因:(?:)就是非捕获分组,此时是不占用组号的。
//(?:) (?=) (?!)都是非捕获分组//更多的使用第一个
//String regex1 ="[1-9]\\d{16}(?:\\d|x|x)\\1";
String regex2 ="[1-9]\\d{16}(\\d Xx)\\1";
//^([01]\d|2[0-3]):[0-5]\d:[@-5]\d$
System.out.println("41080119930228457x".matches(regex2));
}
}
JDK7以前的时间类
package 关于时间类;
import java.util.Date;
public class JDK7以前的 {
public static void main(String[] args) {
//1.创建对象表示一个时间
Date d1 = new Date();
System.out.println(d1);
//2.创建对象表示一个指定的时间,在时间原点的基础上加上给的毫秒
Date d2 = new Date(500000L);
System.out.println(d2);//Thu Jan 01 08:08:20 CST 1970
//3.settime 修改时间
//1000毫秒=1秒
d2.setTime(200000L);
System.out.println(d2);//Thu Jan 01 08:03:20 CST 1970
//4.getTime获取当前时间的毫秒值,即以时间原点为起点的时间差
long time = d2.getTime();
System.out.println(time);//2000
}
}
simpledateformat类
//空参构造,默认格式
SimpleDateFormat sd=new SimpleDateFormat();//默认格式
Date d=new Date();
String now=sd.format(d);
System.out.println(now);//2023/12/21 14:51
//带参构造,指定格式
SimpleDateFormat sd1=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EE");//指定格式
Date d1=new Date();
String now1=sd1.format(d1);
System.out.println(now1);//2023年12月21日 15:23:01 周四
// 细节:
//创建对象的格式要跟字符串的格式完全一致
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str);
//3.打印结果
System.out.println(date);//Sat Nov 11 11:11:11 CST 2023
Calendar
//1.获取日历对象
//细节1:Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象
//底层原理:
//会根据系统的不同时区来获取不同的日历对象,默认表示当前时间。
//把会把时间中的纪元,年,月,日,时,分,秒,星期,等等的都放到一个数组当中
//日 :纪元
// 1 :年
// 2 :月
// 3 : 一年中的第几周
// 4:一个月中的第几周
// 5: 一个月中的第几天(日期)
// ....
//细节2:
//月份:范围0~11 如果获取出来的是.那么实际上是1月。
//星期:在老外的眼里,星期日是一周中的第一天
// 1(星期日) 2(星期一) 3(星期二) 4(星期三) 5(星期四) 6(星期五) 7(星期六)
Calendar c = Calendar.getInstance();
//2.修改一下日历代表的时间
Date d = new Date(0L);
c.setTime(d);
System.out.println(c);
//puslic int get(int field) 取日期中的某个字段信息
//public void set(int field,int value) 修改日历的某个字段信息
//public void add(int fieldint amount) 为某个字段增加/减少指定的值
c.set(Calendar.YEAR, 2023);
c.set(Calendar.MONTH, 8);
c.set(Calendar.DAY_OF_MONTH, 10);
//调用方法在这个基础上增加一个月
c.add(Calendar.MONTH, -1);
//java在Calendar类中,把索引对应的数字都定义成常量
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int date = c.get(Calendar.DAY_OF_MONTH);
int week = c.get(Calendar.DAY_OF_WEEK);
System.out.println(year + "," + month + "," + date + "," + getWeek(week));
}
//查表法://表:容器
//让数据跟索引产生对应的关系
//传入对应的数字: 1 ~7//返回对应的星期
public static String getWeek(int index) {
//定义一个数组,让汉字星期几 跟1~7产生对应关系
String[] arr = {"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
//根据索引返回对应的星期
return arr[index];
JDK8新增的时间类
/*
static Set<string> getAvailableZoneIds() 获取Java中支持的所有时区
static ZoneId systemDefault() 获取系统默认时区
static Zoneld of(string zoneld) 获取一个指定时区
*/
//1.获取所有的时区名称
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
System.out.println(zoneIds.size());//600
System.out.println(zoneIds);// Asia/Shanghai
//2.获取当前系统的默认时区
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);//Asia/Shanghai
//3.获取指定的时区
ZoneId zoneId1 = ZoneId.of("Asia/Pontianak");
System.out.println(zoneId1);//Asia/Pontianak
/*
static Instant now() 获取当前时间的Instant对象(标准时间)
static Instant ofXxxx(long epochMilli) 根据(秒/毫秒/纳秒)获取Instant对象
ZonedDateTime atZone(ZoneIdzone) 指定时区
boolean isxxx(Instant otherInstant) 判断系列的方法
Instant minusXxx(long millisToSubtract) 减少时间系列的方法
Instant plusXxx(long millisToSubtract) 增加时间系列的方法
*/
//1.获取当前时间的Instant对象(标准时间)
Instant now = Instant.now();
System.out.println(now);
//2.根据(秒/毫秒/纳秒)获取Instant对象
Instant instant1 = Instant.ofEpochMilli(0L);
System.out.println(instant1);//1970-01-01T00:00:00z
Instant instant2 = Instant.ofEpochSecond(1L);
System.out.println(instant2);//1970-01-01T00:00:01Z
Instant instant3 = Instant.ofEpochSecond(1L, 1000000000L);
System.out.println(instant3);//1970-01-01T00:00:027
//3. 指定时区
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(time);
//4.isXxx 判断
Instant instant4=Instant.ofEpochMilli(0L);
Instant instant5 =Instant.ofEpochMilli(1000L);
//5.用于时间的判断
//isBefore:判断调用者代表的时间是否在参数表示时间的前面
boolean result1=instant4.isBefore(instant5);
System.out.println(result1);//true
//isAfter:判断调用者代表的时间是否在参数表示时间的后面
boolean result2 = instant4.isAfter(instant5);
System.out.println(result2);//false
//6.Instant minusXxx(long millisToSubtract) 减少时间系列的方法
Instant instant6 =Instant.ofEpochMilli(3000L);
System.out.println(instant6);//1970-01-01T00:00:03Z
Instant instant7 =instant6.minusSeconds(1);
System.out.println(instant7);//1970-01-01T00:00:02Z
/*
static ZonedDateTime now() 获取当前时间的ZonedDateTime对象
static ZonedDateTime ofXxxx(。。。) 获取指定时间的ZonedDateTime对象
ZonedDateTime withXxx(时间) 修改时间系列的方法
ZonedDateTime minusXxx(时间) 减少时间系列的方法
ZonedDateTime plusXxx(时间) 增加时间系列的方法
*/
//1.获取当前时间对象(带时区)
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
//2.获取指定的时间对象(带时区)1/年月日时分秒纳秒方式指定
ZonedDateTime time1 = ZonedDateTime.of(2023, 10, 1,
11, 12, 12, 0, ZoneId.of("Asia/Shanghai"));
System.out.println(time1);
//通过Instant + 时区的方式指定获取时间对象
Instant instant = Instant.ofEpochMilli(0L);
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime time2 = ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(time2);
//3.withXxx 修改时间系列的方法
ZonedDateTime time3 = time2.withYear(2000);
System.out.println(time3);
//4. 减少时间
ZonedDateTime time4 = time3.minusYears(1);
System.out.println(time4);
//5.增加时间
ZonedDateTime time5 = time4.plusYears(1);
System.out.println(time5);
/*
static DateTimeFormatter ofPattern(格式) 获取格式对象
String format(时间对象) 按照指定方式格式化
*/
//获取时间对象
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
// 解析/格式化器
DateTimeFormatter dtf1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm;ss EE a");
// 格式化
System.out.println(dtf1.format(time));
具体观看黑马视频
// 当前本地 年月日
LocalDate today = LocalDate.now();
System.out.println(today);
// 生日的 年月日
LocalDate birthDate = LocalDate.of(2000, 1, 1);
System.out.println(birthDate);
Period period = Period.between(birthDate, today);//第二个参数减第一个参数
System.out.println("相差的时间间隔对象:" + period);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
System.out.println(period.toTotalMonths());//获取总的相差多少个月
// 本地日期时间对象。
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
// 出生的日期时间对象
LocalDateTime birthDate = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
System.out.println(birthDate);
Duration duration = Duration.between(birthDate, today);//第二个参数减第一个参数
System.out.println("相差的时间间隔对象:" + duration);
System.out.println("============================================");
System.out.println(duration.toDays());//两个时间差的天数
System.out.println(duration.toHours());//两个时间差的小时数
System.out.println(duration.toMinutes());//两个时间差的分钟数
System.out.println(duration.toMillis());//两个时间差的毫秒数
System.out.println(duration.toNanos());//两个时间差的纳秒数
// 当前时间
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
// 生日时间
LocalDateTime birthDate = LocalDateTime.of(2000, 1, 1,
0, 0, 0);
System.out.println(birthDate);
System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));
System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));
System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
包装类
把基本数据类型变成了引用数据类型
集合只能存储对象,不能存基本数据类型,所以需要包装类
//在JDK5的时候提出了一个机制:自动装箱和自动拆箱
//自动装箱:把基本数据类型会自动的变成其对应的包装类
//自动拆箱:把包装类自动的变成其对象的基本数据类型
//在底层,此时还会去自动调用静态方法valueof得到一个Integer对象,只不过这个动作不需要我们自己去操作了
//自动装箱的动作
Integer i1 = 10;
Integer i2 = new Integer(10);
//自动拆箱的动作
int i = i2;
//结论:在JDK5以后,int和Integer可以看做是同一个东西,因为在内部可以自动转化。
/*
public static string tobinarystring(int i) 得到二进制
public static string tooctalstring(int i) 得到八进制
public static string toHexstring(int i) 得到十六进制
public static int parseInt(string s) 将字符串类型的整数转成int类型的整数
*/
//1.把整数转成二进制,十六进制
String str1 = Integer.toBinaryString(100);
System.out.println(str1);//1100100
//2.把整数转成八进制
String str2 = Integer.toOctalString(100);
System.out.println(str2);//144
//3.把整数转成十六进制
String str3 = Integer.toHexString(100);
System.out.println(str3);//64
//4.将字符串类型的整数转成int类型的整数
//强类型语言:每种数据在java中都有各自的数据类型
//在计算的时候,如果不是同一种数据类型,是无法直接计算的。
int i = Integer.parseInt("123");
System.out.println(i);
System.out.println(i + 1);//124
//细节1:
//在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
//细节2:
//8种包装类当中,除了Character都有对应的parseXxx的方法,进行类型转换
String str = "true";
boolean b = Boolean.parseBoolean(str);
System.out.println(b);
录入细节
//键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
/* String str = sc.next();
System.out.println(str);*/
//弊端:
//当我们在使用next,nextInt,nextDouble在接收数据的时候,遇到空格,回车,制表符的时候就停止了
//键盘录入的是123 123 那么此时只能接收到空格前面的数据
//我想要的是接收一整行数据
//约定:
//以后我们如果想要键盘录入,不管什么类型,统一使用nextLine
//特点:遇到回车才停止
String line = sc.nextLine();
System.out.println(line);
double v = Double.parseDouble(line);
System.out.println(v);
练习
/*
键盘录入一些1~10日之间的整数,并添加到集合中。直到集合中所有数据和超过200为止。
*/
//1.创建一个集合用来添加整数
ArrayList<Integer> list = new ArrayList<>();
//2.键盘录入数据添加到集合中
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入一个整数");
String numStr = sc.nextLine();
int num = Integer.parseInt(numStr);//先把异常数据先进行过滤
if (num < 1 || num > 100){
System.out.println("当前数字不在1~100的范围当中,请重新输入");
continue;
}
//添加到集合中//细节:
//num:基本数据类型
//集合里面的数据是Integer
//在添加数据的时候触发了自动装箱
list.add(num);
//统计集合中所有的数据和
int sum = getSum(list);
//对sum进行判断
if(sum > 200){
System.out.println("集合中所有的数据和已经满足要求");
break;
}
}
}
private static int getSum(ArrayList<Integer> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
//i :索引
//list.get(i);
int num = list.get(i);
sum = sum + num;//+=
}
return sum;
}