网站建设自学 优帮云/怎样申请网站注册

网站建设自学 优帮云,怎样申请网站注册,成都小程序开发价格,北京今天最新新闻常用API Math类 帮助我们进行数学计算的工具类。 里面的方法都是静态的。 3.常见方法如下: abs:获取绝对值 absExact:获取绝对值 ceil:向上取整 floor:向下取整 round:四舍五入 max:获取最大值 …

 常用API 

  Math类

帮助我们进行数学计算的工具类。

里面的方法都是静态的。

3.常见方法如下:

abs:获取绝对值                  absExact:获取绝对值

ceil:向上取整                        floor:向下取整                round:四舍五入

max:获取最大值                     min:获取最小值

pow:获取a的b次幂                sqrt:开平方根                cbrt:开立方根

random:获取[0.0,1.0]之间的随机数

System类

工具类,提供了一些与系统相关的方法

时间原点: 1970,1月1日0:0:0,我国在东八区,有八个小时时差

1秒=1000毫秒

static voidarraycopy​(Object src, int srcPos, Object dest, int destPos, int length)

将指定源数组中的数组从指定位置开始复制到目标数组的指定位置。

src:数据源,要拷贝的数据从哪个数组来

srcPos:从数据源数组的第几个索引开始拷贝

dest:目的地,我要把数据拷贝到哪个数组中

destPos:目的地数组的索引

length:拷贝的个数

细节:

1.如果数据源数组和目的数组都是 基本数据类型,那么两者类型必须保持一致,否则会报错

2.在拷贝的时候需要考虑数组的长度,如果超出范围也会报错。

3.如果数据源数组和目的数组都是引用数据类型,那么子类类型可以赋值给父类类型

static longcurrentTimeMillis()

以毫秒为单位返回当前时间。

static voidexit​(int status)

终止当前运行的Java虚拟机

 Runtime类

runtime 表示当前虚拟机的运行环境。只能有一个对象。

    • Processexec​(String command)

      在单独的进程中执行指定的字符串命令。

      运行cmd命令

shutdown:关机,加上参数才能执行 -s :默认在1分钟之后关机-s -t 指定时间:指定关机时间

-a 取消关机操作  -r:关机并重启

   Runtime.getRuntime().exec("shutdown -s -t 3600");

    • longfreeMemory()

      返回Java虚拟机中的可用内存量。(单位byte)

    • longtotalMemory()

      返回Java虚拟机中的内存总量。(单位byte)

    • static RuntimegetRuntime()

      返回与当前Java应用程序关联的运行时对象。

    • longmaxMemory()

      返回Java虚拟机将尝试使用的最大内存量。(单位byte)

    • static RuntimegetRuntime()

      返回与当前Java应用程序关联的运行时对象。

    • voidexit​(int status)

      通过启动其关闭序列来终止当前运行的Java虚拟机。

    • intavailableProcessors()

      返回Java虚拟机可用的处理器数。

      获取cpu的线程数

object类 

object是Java中的顶级父类。所有的类都直接或者间接的继承于object类

object类中的方法可以被所有子类访问,所以我们要学习object类和其中的方法。

    • StringtoString()

      返回对象的字符串表示形式。

结论:

 如果我们打印一个对象,想要看到属性值的话,那么就重写toString方法就可以了。再重写的方法中,把对象的属性值进行拼接。

    • booleanequals​(Object obj)

      指示某个其他对象是否“等于”此对象。

  底层中,equals是用 ==来比较地址值的,可以重写equals方法,可以快捷生成-按alt+insert

选equals()and hashCode() 。

    • protected Objectclone()

      创建并返回此对象的副本。

 对象克隆

把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制。

 public static void main(String[] args) throws CloneNotSupportedException {//1.先创建一个对象Pet p1=new Pet("小狗");//2.克隆//细节://方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去//书写细节://1.重写Object类中的clone方法1//2.让javabean类实现Cloneable接口//3.创建原对象并调用clone就可以了。Pet p2= (Pet) p1.clone();System.out.println(p1);System.out.println(p2);}
----------------------------------------------
package com.htu.bean;import java.util.Objects;/*
* 宠物
* *///Cloneable
//如果一个接口里面没有抽象方法
//表示当前的接口是一个标记性接口
//现在Cloneable表示一旦实现了,那么当前类的对象就可以被克隆
//如果没有实现,当前类的对象就不能克隆
public class Pet implements Cloneable{private String name;public Pet() {}public Pet(String name) {this.name = name;}public String  getName(){return name;}public void setName(String name){this.name=name;}@Overridepublic String toString(){return "Pet{"+"'name='"+name+'\''+'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Pet pet = (Pet) o;return Objects.equals(name, pet.name);}@Overridepublic Object clone() throws CloneNotSupportedException {//调用父类中的clone方法//相当于让个JAVA帮我们克隆一个对象,并把克隆之后的的对象返回出去。return super.clone();}
}
 浅克隆与深克隆

 浅克隆:不管对象内部属性是基本数据类型还是引用数据类型,都完全拷贝过来

深克隆:基本数据类型拷贝过来、字符串复用、引用数据类型会重新创建新的。

Object 中的克隆是浅克隆。 

需要深克隆需要重写方法或者使用第三方工具类

package com.htu.bean;import com.google.gson.Gson;
import com.htu.bean.Pet;public class test01 {public static void main(String[] args) throws CloneNotSupportedException {//1.创建一个对象int []data={1,2,3,4,5,6,7,8,9,10};Pet p1=new Pet("小狗",data);//2.克隆Pet p2=(Pet)p1.clone();int []arr= p1.getData();// System.out.println(p1);//System.out.println(p2);//第三方工具//1.第三方写的代码导入到项目中//2.编写代码Gson gson=new Gson();//把对象变成一个字符串String s=gson.toJson(p1);//再把字符串变回对象就可以了Pet pet=gson.fromJson(s,Pet.class);//打印对象arr[0]=100;System.out.println(pet);}}
---------------------------------
package com.htu.bean;import java.util.Objects;
import java.util.StringJoiner;/*
* 宠物
* *///Cloneable
//如果一个接口里面没有抽象方法
//表示当前的接口是一个标记性接口
//现在Cloneable表示一旦实现了,那么当前类的对象就可以被克隆
//如果没有实现,当前类的对象就不能克隆
public class Pet implements Cloneable{private String name;private int []data;public Pet() {}public Pet(String name, int[] data) {this.name = name;this.data = data;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return data*/public int[] getData() {return data;}/*** 设置* @param data*/public void setData(int[] data) {this.data = data;}@Overridepublic String toString(){return "角色编号为:"+name+arrToString();}public String arrToString(){StringJoiner sj=new StringJoiner(",","[", "]");for(int i=0;i<data.length;i++){sj.add(data[i]+"");}return sj.toString();}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Pet pet = (Pet) o;return Objects.equals(name, pet.name);}@Overrideprotected Object clone() throws CloneNotSupportedException {//调用父类中的clone方法//相当于让个JAVA帮我们克隆一个对象,并把克隆之后的的对象返回出去。
//转换成深克隆,方法一,重写方法---数组//先把被克隆对象中的数组获取出来int []data=this.data;//创建新数组int []newData=new int[data.length];//拷贝数组中的数据for (int i = 0; i < data.length; i++) {newData[i]=data[i];}//调用父类中的方法克隆对象Pet p=(Pet) super.clone();//因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值p.data=newData;return p;}}

总结:

1.toString():一般都会重写,打印对象时打印属性

2.equals():比较对象时会重写,比较对象属性值是否相同

3.clone():默认浅克隆

        如果需要深克隆需要重写方法或者是使用第三方工具类。

Objects类

是一个对象工具类,提供了一些方法去完成一些功能。

    • static booleanequals​(Object a, Object b)

      返回 true如果参数相等,彼此 false其他。

      先做非空判断,比较两个对象。

    • static booleanisNull​(Object obj)

      返回 true如果提供的参考是 null ,否则返回 false

      判断对象是否为空。

      static booleannonNull​(Object obj)

      返回 true如果提供的参考是非 null否则返回 false

      判断对象是否不是空。

BigInterger类

在java中,整数有四种类型:byte,short,int,long。

在底层占用字节个数:byte 1个字节 、short 2个字节、int 4个字节、long 8个字节。

构造方法

    • BigInteger​(int numBits, Random rnd)

      构造一个随机生成的BigInteger,均匀分布在0到(2 numBits - 1)的范围内。

    • BigInteger​(String val)

      将BigInteger的十进制字符串表示形式转换为BigInteger。

      字符串中必须是整数,否则会报错。

    • BigInteger​(String val, int radix)

      将指定基数中BigInteger的String表示形式转换为BigInteger

      1.字符串中必须是整数,否则会报错。

      2.字符串中的数字必须要跟进制吻合。

    • static BigIntegervalueOf​(long val)

      返回一个BigInteger,其值等于指定的 long

      静态方法获取BigInteger的对象,内部有优化。

      细节:

      1.能表示范围比较小,只能在long的取值范围之内,如果超出long的范围就不行。

      2.在内部对常用的数字:-16~16进行了优化--提前把-16-16先创建好BigInter的对象,如果多次获取去不会重新创建新的对象。

总结:

1.对象一旦创建,内部记录的值不能改变。

2.如果BigInteger表示的数字没有超出long的范围,可以用静态方法获取。

3.如果BigInteger表示的数字超出long的范围,可以用构造方法获取

4.只要进行计算都会产生一个新的BigInteger对象。

方法:

package com.htu;import java.math.BigInteger;public class BigIntegerDemo2 {public static void main(String[] args) {// 创建BigInteger对象BigInteger bd0=new BigInteger("12");System.out.println(bd0);//1.创建两个BigInteger的对象BigInteger bd1=BigInteger.valueOf(100);BigInteger bd2=BigInteger.valueOf(5);//2.加法BigInteger bd3=bd1.add(bd2);System.out.println(bd3);//3.除法,获取商和余数BigInteger[] arr = bd1.divideAndRemainder(bd2);//0索引是商,1索引是余数System.out.println(arr[0]+" "+arr[1]);//4.比较是否相同boolean result=bd1.equals(bd2);System.out.println(result);//5.次幂BigInteger bd4=bd1.pow(2);System.out.println(bd4);//6.max-返回的是较大数的对象BigInteger bd5=bd1.max(bd2);System.out.println(bd5==bd1);System.out.println(bd5==bd2);//7.转为Int类型整数,超出范围数据有误BigInteger bd6=BigInteger.valueOf(200L);int i = bd6.intValue();System.out.println(i);}
}

BigDecimal

1.用于小数的精确计算

2.用来表示很大的小数

 构造方法:

    • BigDecimal​(double val)

      double转换为 BigDecimal ,它是 double的二进制浮点值的精确十进制表示形式。

    • BigDecimal​(String val)

      BigDecimal的字符串表示 BigDecimal转换为 BigDecimal

    • static BigDecimalvalueOf​(double val)

      转换一个 doubleBigDecimal ,使用 double通过所提供的规范的字符串表示 Double.toString(double)方法。

package com.htu;import java.math.BigDecimal;public class BigDecimalDemo2 {public static void main(String[] args) {//1.通过传递double类型的小数来创建对象//细节://这种方式有可能是不精确的,所以不建议使用/*   BigDecimal bd1=new BigDecimal(0.01);System.out.println(bd1);*///2.通过传递string表示的小数来创建对象BigDecimal bd2=new BigDecimal("0.01");System.out.println(bd2);//3.通过静态方法获取对象BigDecimal bd3=BigDecimal.valueOf(10);System.out.println(bd3);//细节//1.如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法//2.如果要表示的数字大,超出double的取值范围,建议使用构造方法方法//3.如果我们传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新nnew}
}

方法:

package com.htu;import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;public class BigIntegerDemo2 {public static void main(String[] args) {BigDecimal bd1=BigDecimal.valueOf(10.0);BigDecimal bd2=BigDecimal.valueOf(3.0);//1.加法BigDecimal bd3= bd1.add(bd2);System.out.println(bd3);//2.除法//细节:不能除尽的话会报错/* BigDecimal bd4=bd1.divide(bd2);System.out.println(bd4);*/BigDecimal bd5=bd1.divide(bd2,2, RoundingMode.HALF_UP);System.out.println(bd5);}
}

正则表达式

1.校验字符串是否满足规则

2.在一段文本中查找满足要求的内容

public boolean matches(String regex):判断是否与正则表达式匹配,匹配返回true
1、字符类(只匹配一个字符) 

eg:

package com.htu;import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;public class BigIntegerDemo2 {public static void main(String[] args) {//一个[]只能匹配一个字符//只能是a b cSystem.out.println("-----------1------------");System.out.println("a".matches("[abc]"));//trueSystem.out.println("z".matches("[abc]"));//falseSystem.out.println("zz".matches("[abc]"));//falseSystem.out.println("zz".matches("[abc][abc]"));//true//不能出现a b cSystem.out.println("-----------2------------");System.out.println("a".matches("[^abc]"));//falseSystem.out.println("z".matches("[^abc]"));//trueSystem.out.println("zz".matches("[^abc]"));//falseSystem.out.println("zz".matches("[^abc][^abc]"));//true//a到z A到Z(包括头尾的范围)System.out.println("-----------3------------");System.out.println("a".matches("[a-zA-Z]"));//trueSystem.out.println("z".matches("[a-zA-Z]"));//trueSystem.out.println("zz".matches("[a-zA-Z]"));//falseSystem.out.println("zz".matches("[a-zA-Z][a-zA-Z]"));//trueSystem.out.println("0".matches("[a-zA-Z]"));//false//[a-d[m-p] a到d,或m到pSystem.out.println("-----------4------------");System.out.println("a".matches("[a-d[m-p]]"));//trueSystem.out.println("z".matches("[a-d[m-p]]"));//falseSystem.out.println("p".matches("[a-d[m-p]]"));//trueSystem.out.println("e".matches("[a-d[m-p]]"));//falseSystem.out.println("0".matches("[a-d[m-p]]"));//false//[a-z&&[def]]  a-z和def的交集 为 :d e f//细节:如果要求两个范围的交集,那么需要写符号&&//如果写成一个&,那么此时&表示就不是交集了,而是一个简简单单的&符号System.out.println("-----------5------------");System.out.println("a".matches("[a-z&&[def]]"));//falseSystem.out.println("a".matches("[a-z&[def]]"));//trueSystem.out.println("&".matches("[a-z&[def]]"));//trueSystem.out.println("f".matches("[a-z&&[def]]"));//trueSystem.out.println("0".matches("[a-z&&[def]]"));//false//[a-z&&[^bc]]  a-z和非bc的交集 等同于[ad-z]System.out.println("-----------6------------");System.out.println("a".matches("[a-z&&[^bc]]"));//trueSystem.out.println("b".matches("[a-z&&[^bc]]"));//falseSystem.out.println("0".matches("[a-z&&[^bc]]"));//false//[a-z&&[^m-p]] a到z和除了m到p的交集 等同于[a-lq-z]System.out.println("-----------7------------");System.out.println("a".matches("[a-z&&[^m-p]]"));//trueSystem.out.println("m".matches("[a-z&&[^m-p]]"));//falseSystem.out.println("0".matches("[a-z&&[^m-p]]"));//false}
}
2.预定义字符(只匹配一个字符) 

\  转义字符  改变后面那个字符原本的含义

package com.htu;import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;public class BigIntegerDemo2 {public static void main(String[] args) {System.out.println("以下正则匹配只能校验单个字符");System.out.println("----------------------------------");//.表示任意一个字符System.out.println("你".matches(".."));//falseSystem.out.println("你".matches("."));//trueSystem.out.println("你a".matches(".."));//true// \\d只能是任意的一位数字//简单来记:两个\表示一个\System.out.println("a".matches("\\d"));//falseSystem.out.println("3".matches("\\d"));//trueSystem.out.println("33".matches("\\d"));//falseSystem.out.println("33".matches("\\d\\d"));//true// \\w只能是一位单词字符  [a-zA-Z_0-9]System.out.println("z".matches("\\w"));//trueSystem.out.println("2".matches("\\w"));//trueSystem.out.println("21".matches("\\w"));//falseSystem.out.println("你".matches("\\w"));//falseSystem.out.println("_".matches("\\w"));//true// 非单词字符System.out.println("你".matches("\\W"));//trueSystem.out.println("2".matches("\\W"));//false}
}
3、数量词

package com.htu;import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;public class BigIntegerDemo2 {public static void main(String[] args) {//必须是数字 字母 下划线 至少6位System.out.println("2442fsfsf".matches("\\w{6,}"));//trueSystem.out.println("244f".matches("\\w{6,}"));//false//必须是数字和字符 必须是四位System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));//trueSystem.out.println("23_F".matches("[a-zA-Z0-9]{4}"));//falseSystem.out.println("23dF".matches("[\\w&&[^_]]{4}"));//trueSystem.out.println("23_F".matches("[\\w&&[^_]]{4}"));//false}
}
4.正则表达式小结 

 正则表达式的作用:

1.验证字符串

2.爬虫

爬虫

Pattern类:表示正则表达式

Matcher类:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。在大串中去找符合匹配规则的子串。

String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,"+"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在不久的未来Java17也会登上历史舞台";//获取正则表达式的对象Pattern p =Pattern.compile("Java\\d{0,2}");Pattern p2=Pattern.compile("\\d{0,2}");Matcher m2=p2.matcher(str);while(m2.find()){String s1= m2.group();System.out.println(s1);}//获取文本匹配器的对象//m:文本匹配器的对象//str:大串//p:规则//m要在str中找符合p规则的小串Matcher m=p.matcher(str);//利用循环返回/* while(m.find()){String s1=m.group();System.out.println(s1);}
*//*  //拿着文本匹配器从头开始读取,寻找是否有满足规则的子串//如果没有,方法返回false//如果有,返回true.在底层记录子串的启示索引和结束索引+1//在底层索引会记录0和4boolean b=m.find();//方法底层会根据find方法记录的索引进行字符串的截取//字符串的截取方法:subString(起始索引,结束索引);包头不保尾//(0,4)但不包含4索引//会把截取的小串进行返回String s1=m.group();System.out.println(s1);*/-----------------------练习,带有选择性的String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,"+"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在不久的未来Java17也会登上历史舞台";//需求1:爬取版本号为8,11,17,的java文本,但是只要java,不显示版本号String regex1="Java(?=17||8||11)";Pattern p1= Pattern.compile(regex1);//获取正则表达式的对象Matcher m1=p1.matcher(str);//获取文本匹配器的对象while(m1.find()){String s1=m1.group();//返回截取的串System.out.println(s1);}//需求2:爬取版本号为8,11,17的java文本,正确爬取结果为:java8,java11,java17 ,java17String regex2="(?i)java[?=17||11||8]{0,2}";Pattern p1=Pattern.compile(regex2);Matcher m2=p1.matcher(str);while(m2.find()){String s2=m2.group();System.out.println(s2);}//需求3:爬取除了版本号为8,11,17,的java文本String regex3="^((?i)java[?=11||17||8]{0,2})";Pattern p3=Pattern.compile(regex3);Matcher m3=p3.matcher(str);while(m3.find()){String s3=m3.group();System.out.println(s3);}
//---------------------------------贪婪爬取和非贪婪爬取//ab+://贪婪爬取:abbbbbbbbbbbbbbb-尽可能多的获取,默认为贪婪爬取//非贪婪爬取:ab-尽可能少的获取,需要在数量词+ *的后面加上?String str3="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,"+"abbbbbbbbbbb"+"因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在不久的未来Java17也会登上历史舞台";//需求1:尽可能多的获取/*     String regex4="ab+";Pattern p4=Pattern.compile(regex4);Matcher m4=p4.matcher(str3);while(m4.find()){String s4=m4.group();System.out.println(s4);//abbbbbbbbbbb}
*/String regex5="ab+?";Pattern p5=Pattern.compile(regex5);Matcher m5=p5.matcher(str3);while(m5.find()){String s5=m5.group();System.out.println(s5);//ab}
 正则表达式在字符串方法中的使用

 分组

        //---------------捕获分组练习//捕获分组就是把这一组的数据捕获出来,再用一次//需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符//举例: a123a b456b &abc& a123b(false)// \\组号:表示把第x组的内容再出来用一次String regex1="(.).+\\1";System.out.println("a123a".matches(regex1));System.out.println("b456b".matches(regex1));System.out.println("&abc&".matches(regex1));System.out.println("a123b".matches(regex1));//需求2:判断一个字符串的开始部分和结束部分符是否一致?可以有多个字符//举例: abc123abc b456b 123789123 &!abc@! abc122223abd(false)String regex2="(.+).+\\1";System.out.println("abc123abc".matches(regex2));System.out.println("b456b".matches(regex2));System.out.println("123789123".matches(regex2));System.out.println("&!abc@!".matches(regex2));//需求3:判断一个字符串的开始部分和结束部分符是否一致?开始部分内部每个字符也需要一致//举例: aaa123aaa  bbb456bbb 111789111 &&abc&&String regex3="((.)\\2*).+\\1";System.out.println("aaa123aaa".matches(regex3));System.out.println("bbb456bbb".matches(regex3));System.out.println("121789121".matches(regex3));System.out.println("&&abc&&".matches(regex3));
 捕获分组

后续还要继续使用本组的数据。

正则内部使用:\\组号

正则外部使用:$组号

    //需求:将字符串:我要学学编编编编程程程程程程。替换为:我要学编程String str4="我要学学编编编编程程程程程程";//(.)表示把重复内容的第一个字看做第一组//\\1表示第一个字符再次出现//+ 至少一次//$1表示把正则表达式中第一组的内容,再拿出来用String result=str4.replaceAll("(.)\\1+","$1");System.out.println(result);//我要学编程
非捕获分组 

 

//非捕获分组:仅仅是把数据括起来,不占用组号String regex1="[1-9]\\d{16}(?:\\d|X|x)\\1";//\\1报错,原因:(?:)是非捕获分组,此时是不占用组号的//(?:)(?=)(?!)都是非捕获分组

JDK7之前时间相关类 

1.Date  时间类
前提知识

1.世界标准时间:之前是格林威治时间简称GMT,目前世界标准时间(UTC)已经替换为:原子钟。

2.中国在东八区,世界标准时间+8小时

3.时间单位换算: 1秒=1000毫秒 1毫秒=1000微秒  1微秒=1000纳秒

Date类是一个JDK写好的javabean类,用来描述时间,精确到毫秒。

利用空参构造创建的对象,默认表示系统当前时间

利用有参构造创建的对象,表示特定的时间

/*public Date()  //创建Date对象,表示当前时间public Date(long date) //创建Date对象,表示指定时间--从时间原点开始过了多少毫秒public void setTime(long time) //设置、修改毫秒值public long getTime() //获取时间对象的毫秒值*///1.创建对象表示一个时间Date d1=new Date();// System.out.println(d1);//2.创建对象表示一个指定的时间Date d2=new Date(0L);System.out.println(d2);//3.d2.setTime(1000L);System.out.println(d2);//4.long time =d2.getTime();System.out.println(time);// setime();}private static void setime() {//需求1:打印时间原点开始一年后的时间Date d5=new Date(0L);//创建一个对象,表示时间原点long time = d5.getTime();//获取时间原点的毫秒值time=time+1000L*60*60*24*365;//加上一年的毫秒值d5.setTime(time);//把计算后的时间毫秒值设置回d1中System.out.println(d5);}
2.SimpleDateFormst 格式化时间

格式化:把时间编程我们喜欢的格式。

解析:把字符串表示的时间变成Date对象。

格式化的时间形式常用的模式对应关系:

y 年 M 月 d 日 H 时 m 分 s 秒

eg:2023-11-11 11:27:06    ---->yyyy-MM-dd HH:mm:ss;

或者是:2023年11月11日 11时27分06秒    ---->yyyy年MM月dd日 HH时mm分ss秒

  

     //1.利用空参构造创建对象,默认格式SimpleDateFormat s=new SimpleDateFormat();Date d=new Date(0L);String str =s.format(d);System.out.println(str);//1970/1/1 上午8:00//2.利用带参构造创建对象,指定格式SimpleDateFormat s2=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");Date d=new Date(0L);String str2 =s2.format(d);//System.out.println(str2);//1970年01月01日 08:00:00//yyyy年MM月dd日 时 分 秒 星期SimpleDateFormat s3=new SimpleDateFormat("yyyy年MM月dd日 HH时:mm分:ss秒 E ");String str3 =s3.format(d);System.out.println(str3);//解析String str="2023-12-12 11:13:22";//细节:创建对象的格式要跟字符串的格式完全一致SimpleDateFormat  sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date d4=sdf.parse(str);System.out.println(d4.getTime());//1702350802000
 3.Calendar 日历

Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年,月,日。

细节:Calendar是一个抽象类,不能直接创建对象。

      //1.获取日历对象//细节1:Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到了子类对象//底层原理://会根据系统的不同时区来获得不同的日历对象,默认表示当前时间//会把时间中的纪元,年,月,日,时,分,秒,星期。等等的都放到一个数组当中//0索引:纪元;1索引:年 2月  3一年中的第几周 4一个月中的第几周 5一个月中的第几天//细节2://月份:范围0~11 如果获取出来的时0,那么实际上是1月。//星期:在老外眼里,星期日是一周中的第一天//      1->星期日 2->星期一Calendar c=Calendar.getInstance();//2.修改一下日历代表的时间Date d =new Date(0L);c.setTime(d);System.out.println(c);c.set(Calendar.YEAR,2004);c.set(Calendar.MONTH,13);//年份会向后推c.add(Calendar.YEAR,1);//正数 加,负数 减//java在Calendar类中,把索引都定义为了常量int year = c.get(Calendar.YEAR);System.out.println(year);int week = c.get(Calendar.DAY_OF_WEEK);System.out.println(week);

JDK8新增时间相关类 

JDK8时间类 

Zoneld时区

     //1.获取所有时区的名称Set<String> zoneIds= ZoneId.getAvailableZoneIds();System.out.println(zoneIds.size());//603System.out.println(zoneIds);//2.获取当前系统的默认时区ZoneId zoneId=ZoneId.systemDefault();System.out.println(zoneId);//GMT+08:00//3.获取指定时区ZoneId zoneId1=ZoneId.of("America/Cuiaba");System.out.println(zoneId1);
Instant时间戳

   //1.获取当前时间的instant对象(标准时间)Instant now = Instant.now();System.out.println(now);//2023-09-24T07:18:16.450867900Z//2.根据(秒、毫秒、纳秒)获取Instant对象Instant instant1=Instant.ofEpochMilli(0L);System.out.println(instant1);//1970-01-01T00:00:00ZInstant instant2=Instant.ofEpochSecond(1L);System.out.println(instant2);//1970-01-01T00:00:01ZInstant instant3=Instant.ofEpochSecond(1L,1000000000L);System.out.println(instant3);//1970-01-01T00:00:02Z//3.指定时区ZonedDateTime time = Instant.now().atZone(ZoneId.of("America/Cuiaba"));System.out.println(time);//2023-09-24T03:24:59.933331500-04:00[America/Cuiaba]
 ZoneDateTime带时区的时间
 DateTimeFormatter用于时间的格式化和解析

 

 包装类

包装类:基本数据类型对应的引用数据类型

以Integer为例,其余都一样

Integer

JDK5之前:

package api;public class IntegerDemo {public static void main(String[] args) {//1.利用构造方法获取Integer对象(JDK5之前)Integer i1=new Integer(1);Integer i2 =new Integer("1");System.out.println(i1);//1System.out.println(i2);//1//2.利用静态方法获取Integer的对象(JDK5之前)Integer i3=Integer.valueOf(123);Integer i4=Integer.valueOf("123");Integer i5=Integer.valueOf("123",8);System.out.println(i3);//123System.out.println(i4);//123System.out.println(i5);//83//3.这两种方式获取对象的区别(掌握)//底层原理://因为在实际开发中,-128~127之间的数据,用的比较多//如果每次使用都是new对象,那么太浪费内存了//所以,提前把这个范围之内的每一个数据都创建好对象//如果要用到了不会创建新的,而是返回已经创建好的对象。Integer i6=Integer.valueOf(127);Integer i7=Integer.valueOf(127);System.out.println(i6==i7);//trueInteger i8=Integer.valueOf(128);Integer i9=Integer.valueOf(128);System.out.println(i8==i9);//false//因为看到了new关键字,在java中,每一次new都是创建了一个新的对象//所以下面的两个对象都是new出来的,地址值不一样Integer i10=new Integer(127);Integer i11=new Integer(127);System.out.println(i10==i11);//falseInteger i12=new Integer(128);Integer i13=new Integer(128);System.out.println(i12==i13);//false}
}

JDK5之后的机制: 

package api;public class IntegerDemo {public static void main(String[] args) {/*  //在以前包装类如何进行计算Integer i1=new Integer(1);Integer i2=new Integer(2);//需求:要把这两个数据进行相加得到结果3//对象质检室不能直接进行计算的//步骤:1.把对象进行拆箱,变为基本数据类型  2.相加  3.把得到的结果再次进行装箱(再变为包装类)int result=i1.intValue()+i2.intValue();Integer i3=new Integer(result);System.out.println(i3);*///在JDK5的时候提出了一个机制:自动装箱和自动拆箱//自动装箱:把基本数据类型会自动的变成其对应得包装类//自动拆箱:把包装类自动的编程其对象的基本数据类型//在底层,此时还会去自动调用静态方法valueof得到一个Integer对象,只不过这个动作不需要我们自己操作//自动装箱Integer i1=10;Integer i2=new Integer(10);//自动拆箱int i=i2;//在JDK5之后,int和Integer可以看作是同一个东西,因为在内部可以自动转化。}
}

Integer成员方法

package api;public class IntegerDemo {public static void main(String[] args) {//1.把整数转成2进制String str1=Integer.toBinaryString(12);System.out.println(str1);//1100//2.把整数转成8进制String str2=Integer.toOctalString(12);System.out.println(str2);//14//3.把整数转成16进制String str3=Integer.toHexString(12);System.out.println(str3);//C//4.将字符串类型的整数转成int类型的整数//强类型语言:每种数据在java中都有各自的数据类型//在计算的时候,如果不是同一种数据类型,是无法直接计算的int i=Integer.parseInt("123");System.out.println(i);//123//细节:1.在类型转换的时候,括号中的参数只能是数字不能是其他,负责代码会报错//2.8中包装类中,除了character都有对应的parsexxx的方法,进行类型转换String str="true";boolean b=Boolean.parseBoolean(str);System.out.println(b);//true}
}

 键盘录入改进

      //以后如果想键盘录入,不管什么类型,统一使用nextLine//特点:遇到回车才停止Scanner sc=new Scanner(System.in);String line=sc.nextLine();double v=Double.parseDouble(line);System.out.println(v+1);

 案例:

package api;public class IntegerDemo {public static void main(String[] args) {/** 键盘录入一些1~100之间的整数,并添加到集合中* 直到集合中所有数据和超过200为止* */ArrayList<Integer> l=new ArrayList<>();Scanner sc=new Scanner(System.in);int sum=0;do{System.out.println("请输入");String line=sc.nextLine();int i=Integer.parseInt(line);if(i<1||i>100){System.out.println("数据输错");continue;}sum=sum+i;l.add(i);}while(sum<=200);for (int i = 0; i < l.size(); i++) {System.out.print(l.get(i)+" ");}
---------------------------------------------/** 自己实现parseInt方法的效果,将字符串形式的数据转成整数* 要求:* 字符串中只能是数字不能有其他字符* 最少一位,最多10位* 0不能开头* */Scanner sc =new Scanner(System.in);System.out.println("请输入:");String line = sc.nextLine();//判断是否符合规则String regx="[1-9]\\d{0,9}";if(line.matches(regx)){//转换成整数int num=0;for (int i = 0; i < line.length(); i++) {char c=line.charAt(i);num=num*10+(c-'0');}System.out.println(num);}else{System.out.println("不符合规则");}}
}

常见算法

查找

顺序查找
package algorithmdemo01;import java.util.ArrayList;public class day01 {public static void main(String[] args) {//基本查找/顺序查找//核心:从0索引开始挨个往后查找//需求:定义一个方法利用基本查找,查询某个元素是否存在//数据如下:{1331,235,89,56,12,0,456,455}int []arr={1331,235,89,56,12,0,456,455,89,89,56};int num=10;ArrayList<Integer> result =new ArrayList<>();result=basicSearch2(arr,num);System.out.println(result);}//顺序查找public static boolean basicSearch(int[] arr,int num){for (int i = 0; i < arr.length; i++) {if(num==arr[i]){return true;}}return false;}//课堂练习1//需求:定义一个方法利用基本查找,查询某个元素在数组中的索引//要求:不需要考虑数组中元素是否重复public static int basicSearch1(int[] arr,int num){for (int i = 0; i < arr.length; i++) {if(num==arr[i]){return i;}}return -1;}//课堂练习2//需求:定义一个方法利用基本查找,查询某个元素在数组中的索引//要求:需要考虑数组中元素重复的可能性-返回所有索引public static ArrayList basicSearch2(int[]arr, int num){ArrayList<Integer> result=new ArrayList<>();for (int i = 0; i < arr.length; i++) {if(num==arr[i]){result.add(i);}}return result;}}
二分查找/折半查找

 前提条件数组中的数据必须是有序的

核心逻辑:每次排除一半的查找范围

过程:

  • min和max表示当前要查找的范围
  • mid是在min和max中间的
  • 如果要查找的元素在mid的左边,缩小范围时,min不变,max=mid-1
  • 如果要查找的元素在mid的右边,缩小范围时,max不变,min=mid+1
public class day01 {public static void main(String[] args) {//二分查找/折半查找//核心:每次排除一半的查找范围//需求:定义一个方法利用二分查找,查询某个元素在数组中的索引//数据如下:{1331,235,89,56,12,0,456,455}int []arr={1,2,3,4,5,6,7,8,9,10};int num=10;System.out.println(binarySearch(arr,num));}//二分查找public static int  binarySearch(int[]arr,int num){int min=0,max=arr.length-1,mid=arr.length/2;while(min!=max){if(num>arr[max]||num<arr[min]){return -1;}else if(num==arr[mid]){return mid;}else if(num==arr[min]) {return min;}else if(num==arr[max]){return max;}else if(num>arr[mid]){//进入右部分min=mid+1;}else if(num<arr[mid]){//进入左部分max=mid-1;}mid=(max-min)/2+min;}return -1;}
}
插值查找--二分查找优化

 前提条件数组中的数据必须是有序且分布均匀

过程:同二分查找,但mid的取值按照下面公式得到,让mid尽可能的靠近要查找的数据:

斐波那契查找-二分查找改进

过程:同二分查找,但mid的取值按照下面公式得到:

分块查找

分块原则1:前一块中的最大数据,小于后一块中的所有数据(块内无序,块间有序)

分块原则2:块数数量一般等于数字的个数开根号。比如:16个数字一般分为4块左右。

核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找。

package algorithmdemo01;public class day01 {public static void main(String[] args) {/** 分块查找:* 核心思想:块内无序,块间有序* 实现步骤:* 1.创建数组blockArr存放每一块对象的信息* 2.先查找blockArr确定要查找的数据属于哪一块* 3.再单独遍历这块数据即可* */int []arr={16,5,9,12,21,18,32,23,37,26,45,34,50,48,61,52,73,66};//1.要把数据进行分块//分几块:18开根号--》4block blk1=new block(16,0,3);block blk2=new block(37,4,9);block blk3=new block(50,10,13);block blk4=new block(73,14,17);//创建数组存放对象(索引表)block [] blockArr = {blk1,blk2,blk3,blk4};//定义一个变量用来记录要查找的元素int num=40;System.out.println(BlockSearchIndex(blockArr,num,arr));}//2.查找blockArr确定要查找的数据属于哪一块public static int  BlockSearchIndex(block[] blk,int num,int[]arr){int index;for (int i = 0; i < blk.length; i++) {if(blk[i].getMax()<num){//不在这一块}else if(blk[i].getMax()>=num){//在这一块index=i;int start =blk[index].getStartIndex();int end=blk[index].getEndIndex();return BlockSearch(start,end,arr,num);}}return -1;}//3.再单独遍历这块数据即可public static int BlockSearch(int start,int end,int[] arr,int num){for (int i = start; i <=end; i++) {if(arr[i]==num){return i;}}return -1;}
}class block{private int max;//记录最大的数private int startIndex;//记录起始索引private  int endIndex;//记录结束索引public block() {}public block(int max, int startIndex, int endIndex) {this.max = max;this.startIndex = startIndex;this.endIndex = endIndex;}/*** 获取* @return max*/public int getMax() {return max;}/*** 设置* @param max*/public void setMax(int max) {this.max = max;}/*** 获取* @return startIndex*/public int getStartIndex() {return startIndex;}/*** 设置* @param startIndex*/public void setStartIndex(int startIndex) {this.startIndex = startIndex;}/*** 获取* @return endIndex*/public int getEndIndex() {return endIndex;}/*** 设置* @param endIndex*/public void setEndIndex(int endIndex) {this.endIndex = endIndex;}public String toString() {return "block{max = " + max + ", startIndex = " + startIndex + ", endIndex = " + endIndex + "}";}
}
扩展的分块查找(无规律的数据)

扩展的分块查找(查找过程中还需要添加数据)--哈希查找

排序算法

冒泡排序:

1.相邻的数据两两比较,小的放前面,大的放后面。

2.第一轮比较完毕之后,最大值就已经确定,第二轮可以少循环一次,后面以此类推

3.如果数组中有n个数据,纵观我们只要执行n-1轮的代码就可以。

package algorithmdemo01;public class day01 {public static void main(String[] args) {//冒泡排序//定义数组int[]arr={3,4,5,2,1,0,6,9,8,7};//外循环:表示我要执行多少轮,如果有n各数据,那么执行n-1轮for(int j=0;j<arr.length-1;j++){//内循环:每一轮中我如何比较数据并找到当前的最大值//-1:为了防止索引越界//-i:提高效率,每一轮执行的次数应该比上一轮少一次for(int i=0;i<arr.length-j-1;i++){if(arr[i]>arr[i+1]){//交换位置int temp =arr[i+1];arr[i+1]=arr[i];arr[i]=temp;}}}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}}
选择排序

从0索引开始,拿着每一个索引上的元素跟后面的元素一次比较,晓得放前面,大的放后面,以此类推。

package algorithmdemo01;public class day01 {public static void main(String[] args) {//选择排序int[]arr={8,9,6,5,23,4,2,0,12,56,1};//外循环:循环几轮 ,i表示这一轮中,我拿着哪个索引上的数据跟后面的数据进行比较并交换for (int j = 0;  j< arr.length-1; j++) {//内循环:每一轮我要干什么//拿着i跟i后面的数据进行比较交换for (int i = j+1; i < arr.length; i++) {if(arr[j]>arr[i]){//交换int temp=arr[i];arr[i]=arr[j];arr[j]=temp;}}}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}
}
插入排序

将0索引的元素到N索引的元素看作是有序的,把N+1索引的元素到最后一个当做是无序的。遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如遇到相同的数据,插在后面.N的范围:0~最大索引

package algorithmdemo01;public class day01 {public static void main(String[] args) {//插入排序int []arr={8,9,56,23,0,45,7,5,6,5,10};//1.找到无序的那一组数组是从哪个索引开始的int start=0;for (int i = 0; i < arr.length; i++) {if(arr[i]>arr[i+1]){start=i+1;break;}}//2.遍历从start开始到最后一个元素,依次得到无序的那一组数据值for (int  j=start; j<arr.length; j++) {int i=j;//记录当前要插入数据的索引while(i>0&&arr[i]<arr[i-1]){//交换位置int temp=arr[i];arr[i]=arr[i-1];arr[i-1]=temp;i--;}}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}}
}
快速排序

递归算法:递归指的是方法中调用方法本身的现象。

递归一定要有出口

第一轮:把0索引的数字作为基准书,确定基准数在数组中正确的位置。比基准数小的全部在左边,比基准数大的全部在右边。

Arrays

操作数组的工具类

package algorithmdemo01;import java.util.Arrays;public class myarrays {public static void main(String[] args) {//toString 将数组变成字符串int [] arr={1,2,3,4,5,6,7,8,9,10};System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5, 6, 7, 8, 9,10]//binarySearch 二分法查找//细节1:二分查找的前提:数组中的元素必须是有序,数组中的元素必须是升序的//细节2:如果要查找的元素是存在的,那么返回的是真实的索引// 但是,如果要查找的元素是不存在的,返回的是-插入点-1// 疑问:为什么要减1呢?// 解释:如果此时,我现在要查找数字e.那么如果返回的值是-插入点,就会出现问题了。// 如果要查找数字e.此时e是不存在的,但是按照上面的规则-插入点,应该就是-e// 为了避免这样的情况,Java在这个基础上又减一。System.out.println(Arrays.binarySearch(arr,10));//9System.out.println(Arrays.binarySearch(arr,2));//1System.out.println(Arrays.binarySearch(arr,11));//-11//copyOf:拷贝数组// 参数一:老数组// 参数二:新数组的长度// 方法的底层会根据第二个参数来创建新的数组// 如果新数组的长度是小于老数组的长度,会部分拷贝// 如果新数组的长度是等于老数组的长度,会完全拷贝// 如果新数组的长度是大于老数组的长度,会补上默认初始值int []newArr1=Arrays.copyOf(arr,2);System.out.println(Arrays.toString(newArr1));//[1, 2]int []newArr2=Arrays.copyOf(arr,10);System.out.println(Arrays.toString(newArr2));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]int []newArr3=Arrays.copyOf(arr,20);System.out.println(Arrays.toString(newArr3));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]//copyOfRange:拷贝数组(指定范围)int []newArr4=Arrays.copyOfRange(arr,0,9);System.out.println(Arrays.toString(newArr4));//[1, 2, 3, 4, 5, 6, 7, 8, 9]//fill 填充数组Arrays.fill(arr,100);System.out.println(Arrays.toString(arr));//[100, 100, 100, 100, 100, 100, 100, 100, 100, 100]//sort 排序 默认情况下,给基本数据类型进行升序排序。底层使用得是快速排序int []arr2={10,2,3,5,6,1,8,9,4};Arrays.sort(arr2);System.out.println(Arrays.toString(arr2));//[1, 2, 3, 4, 5, 6, 8, 9, 10]}
}
package algorithmdemo01;import java.util.Arrays;
import java.util.Comparator;public class myarrays01 {/** public static void sort(数组,排序规则)按照指定的顺序排序* 参数一:要排序的数组* 参数二:排序的规则* 细节:只能给引用数据类型的数组进行排序* 如果数组时基本数据类型的,需要变成其对应的包装类** */public static void main(String[] args) {Integer[]arr={1,5,6,8,2,3,4,7,9};//第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。//但是这个实现类,我只要使用一次,所以就没有必要单独的去写一个类,直接采取匿名内部类的方式就可以了//底层原理:// 利用插入排序+二分查找的方式进行排序的。// 默认把0索引的数据当做是有序的序列,1索引到最后认为是无序的序列。// 遍历无序的序列得到里面的每一个元素,假设当前遍历得到的元素是A元素// 把A往有序序列中进行插入,在插入的时候,是利用二分查找确定A元素的插入点。// 拿着A元素,跟插入点的元素进行比较,比较的规则就是compare方法的方法体// 如果方法的返回值是负数,拿着A继续跟前面的数据进行比较// 如果方法的返回值是正数,拿着A继续跟后面的数据进行比较// 如果方法的返回值是0,也拿着A跟后面的数据进行比较// 直到能确定A的最终位置为止。// compare方法的形式参数:// 参数一o1:表示在无序序列中,遍历得到的每一个元素// 参数二o2:有序序列中的元素// 返回值:// 负数:表示当前要插入的元素是小的,放在前面// 正数:表示当前要插入的元素是大的,放在后面// 0:表示当前要插入的元素跟现在的元素比是一样的也会放在后面//简单理解://o1-o2:升序排列//o2-o1:降序排序Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {System.out.println("o1:"+o1+" o2:"+o2);return o2-o1;}});System.out.println(Arrays.toString(arr));//[9, 8, 7, 6, 5, 4, 3, 2, 1]}}

Lambda表达式

面向对象:先找对象,让对象做事情。

函数式编程(Functional programming)是一种思想特点

函数式编程思想,忽略面向对象的复杂语法,强调做什么,而不是谁去做

而我们要学习的Lambda表达式就是函数式思想的体现。

Lambda表达式的标准格式

Lambda表达式是JDK 8开始后的一种新语法形式。

()->{}
  • ()对应着方法的形参
  • ->    固定格式
  •  { }   对应着方法的方法体

注意点:

  • Lambda表达式可以用来简化匿名内部类的书写
  • Lambda表达式只能简化函数式接口的匿名内部类的写法
  • 函数式接口:
    • 有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@Functionallnterface注解

小结:

1、Lambda表达式的基本作用?

简化函数式接口的匿名内部类的写法。

2、Lambda表达式有什么使用前提?

必须是接口的匿名内部类,接口中只能有一个抽象方法

3、Lambda的好处?

Lambda是一个匿名 函数 我们可以把Lambda表达式理解为是一段 可以传递的代码,它可以写出更简洁、更灵活的代码,作为一种更紧 凑的代码风格,使Java语言表达能力得到了提升。

 lambda的省略规则:

省略核心:可推导,可省略

1.参数类型可以省略不写。

2.如果只有一个参数,参数类型可以省略,同时()也可以省略。

3.如果Lambda表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略。

package algorithmdemo01;import java.util.Arrays;
import java.util.Comparator;public class myarrays01 {public static void main(String[] args) {Integer[] arr={1,5,6,7,3,2,4,9,8};//匿名内部类Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1-o2;}});//lambda完整写法Arrays.sort(arr, (o1,o2)->{return o2-o1;});//lambda省略写法Arrays.sort(arr, (Integer o1, Integer o2)->o1-o2);System.out.println(Arrays.toString(arr));}
}

案例

package algorithmdemo01;import java.util.Arrays;public class myarrays01 {public static void main(String[] args) {GirlFriend gf1=new GirlFriend("efag",17,157);GirlFriend gf2=new GirlFriend("abd",18,157);GirlFriend gf3=new GirlFriend("bebe",19,160);GirlFriend gf4=new GirlFriend("gg",17,157);GirlFriend[] gfs={gf1,gf2,gf3,gf4};//排序--匿名内部类Arrays.sort(gfs,new Comparator<GirlFriend>() {@Overridepublic int compare(GirlFriend o1, GirlFriend o2) {//按年龄double temp;temp=o1.getAge()-o2.getAge();//按身高排temp=temp==0?o1.getHeight()-o2.getHeight():temp;*//* if(temp==0){temp=o1.getHeight()-o2.getHeight();}*//*//按名字排temp=temp==0?o1.getName().compareTo(o2.getName()):temp;*//*if(temp==0){temp=o1.getName().compareTo(o2.getName());}*//*if(temp>0)return 1;else if(temp==0)return 0;elsereturn -1;}});//lambdaArrays.sort(gfs, (GirlFriend o1, GirlFriend o2) ->{//按年龄double temp;temp=o1.getAge()-o2.getAge();//按身高排temp=temp==0?o1.getHeight()-o2.getHeight():temp;/* if(temp==0){temp=o1.getHeight()-o2.getHeight();}*///按名字排temp=temp==0?o1.getName().compareTo(o2.getName()):temp;/*if(temp==0){temp=o1.getName().compareTo(o2.getName());}*/if(temp>0)return 1;else if(temp==0)return 0;elsereturn -1;});System.out.println(Arrays.toString(gfs));}
}class GirlFriend{private String name;private int age;private double height;public GirlFriend() {}public GirlFriend(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}/*** 获取* @return height*/public double getHeight() {return height;}/*** 设置* @param height*/public void setHeight(double height) {this.height = height;}public String toString() {return "GirlFriend{name = " + name + ", age = " + age + ", height = " + height + "}";}
}

集合进阶

List系列集合:添加的元素是有序、可重复、有索引

Set系列集合:添加的元素是无序 不重复、无索引

Collection

Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。

方法名称说明
public boolean add(E e)把给定的对象添加到当前集合中
public void clear()清空集合中所有的元素
public boolean remove(E e)把给定的对象在当前集合中删除
public boolean contains(Object obj)判断当前集合中是否包含给定的对象
public boolean isEmpty()判断当前集合是否为空
public int size()返回集合中元素的个数/集合的长度
/** 注意点:collection是一个接口,不能直接创建他的对象。* 所以,现在我们学习他的方法,只能创建他实现类的对象。* 实现类:ArrayList* *///目的:为了学习Collection接口里面的方法// 自己在做一些练习的时候,还是按照之前的方式去创建对象。Collection<String> coll =new ArrayList<>();//1.添加元素细节1:如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列的是允许元素重复的。细节2:如果我们要往Set系列集合中添加数据,如果当能要添加元素不存在,方法返回true,表示添加成功。//                                     如果当前要添加的元素已经存在,方法返回false,表示添加失败。coll.add("aaa");coll.add("bbb");coll.add("ggg");coll.add("fff");coll.add("yyy");System.out.println(coll);//[aaa, bbb, ggg, fff, yyy]//2.clear/*   coll.clear();System.out.println(coll);//[]
*///3.remove 删除// 细节1:因为collection里面定义的是共性的方法,所以此时不能通过索引进行删除。只能通过元素的对象进行删除。// 细节2:方法会有一个布尔类型的返回值,删除成功返回true.删除失败返回false// 如果要删除的元素不存在,就会删除失败。coll.remove("ggg");System.out.println(coll);//[aaa, bbb, fff, yyy]//4.判断元素是否包含//细节;底层是依赖equals方法进行判断是否存在的。//所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法(快捷键Alt+insert)。//字符串在底层已经重写过equals方法了boolean result=coll.contains("bbb");System.out.println(result);//true//5.判断是否为空boolean re=coll.isEmpty();System.out.println(re);//false//6.长度int size=coll.size();System.out.println(size);//4

Collection的遍历方式

原来的for遍历只有list能用,set用不了

迭代器遍历

迭代器不依赖索引

迭代器在Java中的类是lterator,迭代器是集合专用的遍历方式。

Collection集合获取迭代器
Iterator<E> iterator() //返回迭代器对象,默认指向当前集合的0索引
lterator中的常用方法
boolean hasNext()//判断当前位置是否有元素,有元素返回true,没有元素返回false
E next()//获取当前位置的元素,并将迭代器对象移向下一个位置。
void remove() //从带带器指向的collection中移除迭代器返回的最后一个元素 
       //1.创建集合并添加元素Collection<String > coll =new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");//2.获取迭代器对象//迭代器器就好比是一个箭头,默认指向集合0索引处Iterator<String> it=coll.iterator();//3.利用循环不断地去获取集合中的每一个元素while(it.hasNext()){//4.next方法的;两件事情:获取元素并移动指针String str=it.next();if("bbb".equals(str)){it.remove();}System.out.print(str+" ");//aaa bbb ccc}System.out.println();System.out.println(coll);//[aaa, ccc]
 细节注意点:

1,报错NoSuchElementException----当上面循环结束之后,迭代器的指针已经指向最后没有元素的位置

2,迭代器遍历完毕,指针不会复位-----需要重新遍历集合则需要重新获取一个新的迭代器对象

3,循环中只能用一次next方法----否则可能会报错NoSuchElementException;next方法与hasNext方法配套出现

4,迭代器遍历时,不能用集合的方法进行增加或者删除----报错ConcurrentModificationException;用迭代器的remove方法删除,添加暂时没有办法。

增强for遍历
  • 增强for的底层就是迭代器,为了简化迭代器的代码书写的。
  • 它是JDK5之后出现的,其内部原理就是一个lterator迭代器
  • 所有的单列集合和数组才能用增强for进行遍历。
格式:
for(元素的数据类型 变量名:数组或者集合){
}eg:
for(String s:list){}
//1.创建集合并添加元素Collection<String > coll =new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");//s其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个数据for(String s:coll){System.out.print(s+" ");}
Lambda表达式遍历

得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。

default void forEach(Consumer<? super T> action)://结合lambda遍历集合
    //1.创建集合并添加元素Collection<String > coll =new ArrayList<>();coll.add("aaa");coll.add("bbb");coll.add("ccc");//2.利用匿名内部类的形式//底层原理:--封装在ArrayList中//forEach方法底层其实也会自己遍历集合,依次得到每个方法//把得到的每一个元素,传递给下面的accept方法/*   coll.forEach(new Consumer<String>() {@Override//s就是依次表示集合中的每一个数据public void accept(String s) {System.out.print(s+" ");//aaa bbb ccc}});*///lambda表达式coll.forEach(s-> System.out.print(s+" "));//aaa bbb ccc

小结:

1.Collection是单列集合的顶层接口,所有方法被List和Set系列集合共享

2.常见成员方法: add, clear, remove, contains, isEmpty, size

3.三种通用的遍历方式:

  • 在遍历的过程中需要删除元素,请使用迭代器。
  • 仅仅想遍历,那么使用增强for或Lambda表达式

List集合

  • Collection的方法List都继承了
  • List集合因为有索引,所以多了很多索引操作的方法。
方法名称说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素
       //1.创建集合并添加元素List<String> list=new ArrayList<>();//2.添加元素list.add("aaa");list.add("bbb");list.add("ccc");//void add(int index,E element)//细节:原来索引上的元素会依次往后移list.add(1,"888");//E remove(int index)//细节:在调用方法的时候,如果方法出现了重载现象//优先调用,实参跟形参类型一致的那个方法。String remove=list.remove(0);System.out.println(remove);//E set(int index,E element)String set=list.set(2,"000");System.out.println(set);//返回被修改索引的元素//E get(int index)String s= list.get(0);//返回指定索引处的元素System.out.println(s);System.out.println(list);
list集合的遍历方式
  • 迭代器遍历
    • 在遍历的过程中需要删除元素,请使用迭代器。
  • 列表迭代器遍历
    • 在遍历的过程中需要添加元素,请使用列表迭代器。
  • 增强for遍历
    • 仅仅想遍历,那么使用增强for或Lambda表达式。
  • Lambda表达式遍历
    • 仅仅想遍历,那么使用增强for或Lambda表达式。
  • 普通for循环(因为List集合存在索引)
    • 如果遍历的时候想操作索引,可以用普通for。
//1.创建集合并添加元素List<String> list=new ArrayList<>();//2.添加元素list.add("aaa");list.add("bbb");list.add("ccc");//迭代器Iterator<String> it=list.iterator();while(it.hasNext()){String s=it.next();System.out.print(s+" ");}//增强forfor(String s:list){System.out.print(s+" ");}//lambdalist.forEach(s->System.out.print(s+" "));//普通forfor (int i = 0; i < list.size(); i++) {System.out.print(list.get(i)+" ");}//列表迭代器//获取一个列表迭代器的对象,里面的指针默认也是指向0索引的//额外添加了一个方法:在遍历的过程中,可以添加元素--用迭代器的方法添加ListIterator<String>it= list.listIterator();while(it.hasNext()){String str=it.next();if("bbb".equals(str)){it.add("333");}}System.out.print(list);

知识准备----数据结构

栈--先进后出,后进先出

队列--先进先出,后进后出

数组--查询快,增删慢

链表--查询慢,增删快

ArrayList集合底层原理

①利用空参创建的集合,在底层创建一个默认长度为0的数组

②添加第一个元素时,底层会创建一个新的长度为10的数组

③ 存满时,会扩容1.5倍

④如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准

 

LinkedList集合

  • 底层数据结构是双链表,查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的。
  • LinkedList本身多了很多直接操作首尾元素的特有APl

 底层源码

 迭代器底层源码

泛型

泛型:是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查

泛型的格式:<数据类型>

细节:

  1. 指定泛型的具体类型后,传递数据时,可以传入该类类型或者其子类类型
  2. 如果不写泛型,类型默认是Object

注意:泛型只支持引用数据类型

好处:

  1. 统一了数据类型。
  2. 把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来。
import java.util.ArrayList;
import java.util.Iterator;public class datedemo01 {public static void main(String[] args)  {//结论:/** 如果我们没有给集合指定恰当的类型,就认为所有的数据类型都是object类型* 此时可以往集合添加任意的数据类型。* 带来一个坏处:我们在获取数据的时候,无法使用他的特有行为。* 此时推出了泛型,可以在添加数的时候就把类型进行统一。* 而且我们在获取数据的时候,也省的强转了,非常的方便。* */ArrayList<String> list=new ArrayList();list.add("aaa");Iterator<String> it=list.iterator();while(it.hasNext()){String str=it.next();System.out.println(str);}}
}

扩展知识:JAVA中的泛型是伪泛型

  

泛型可以在很多地方进行定义

类后面---》泛型类

方法上面---》泛型方法

接口上面--》泛型接口

泛型类

使用场景:当一个类中,某个变量的数据类型不确定时,就可可以定义带有泛型的类

import java.util.Arrays;public class MyArrayList <E>{Object[] obj=new Object[10];int size;public boolean add(E e){obj[size]=e;size++;return true;}public E get(int index){return (E)obj[index];}@Overridepublic String toString() {return Arrays.toString(obj);}
}
------测试MyArrayList<String> mal=new MyArrayList<>();mal.add("aaa");mal.add("bbb");mal.add("ccc");System.out.println(mal.get(0));System.out.println(mal);
泛型方法

方法中参数类型不确定时

  1. 方案一:使用类名后面定义的泛型---类上定义的泛型在类中都能用
  2. 方案二:在方法声明上定义自己的泛型--只能在本方法中用

import java.util.ArrayList;public class ListUtil {private ListUtil(){}//类中定义一个静态方法addAll,用来添加多个集合的元素public static <E> void addALL(ArrayList <E> list,E e1){list.add(e1);}
}
--------ArrayList<String> list=new ArrayList<>();ListUtil.addALL(list,"aaa");System.out.println(list);
泛型接口

如何使用一个带泛型的接口

  1. 实现类给出具体类型
  2. 实现类延续泛型,创建对象时再确定具体类型
public class MyArrayList2 implements List<String> {...}MyArrayList2 list=new MyArrayList2();
--------------------------------------------------------------
public class MyArrayList3<E> implements List<E> {...}MyArrayList3<String> list3=new MyArrayList3<>();
泛型不具备继承性,但是数据具备继承性
 ArrayList<Ye> list1 = new ArrayList<>();ArrayList<Fu> list2 = new ArrayList<>();ArrayList<Zi> list3 = new ArrayList<>();method(list1);method(list2);//报错method(list3);//报错//此时,泛型里面写的是什么类型,那么只能传递什么类型的数据public static void method(ArrayList<Ye> list) {}--------------------------------------------------------class Ye {
}class Fu extends Ye {
}class Zi extends Fu {
}
泛型的通配符 

 应用场景:

         1.如果我们在定义类、方法、接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口。

         2.如果类型不确定,但是能知道以后只能传递某个继承体系中的,就可以泛型的通配符 

关键点:可以限定类型的范围。

/*希望:本方法虽然不确定是什么类型,但以后希望传递的是YeFuZi此时:我们可以使用泛型的通配符:?也表示不确定的类型但可以进行类型的限定? extendsE:表示可以传递E或者E所有的子类类型? super E:表示可以传递E或者E所有的父类类型*/}public static void method (ArrayList<? extends Ye> list){}

数据结构(树)

二叉查找树

添加节点:

小的存左边,大的存右边,一样的不存

平衡二叉树

规则:任意节点左右子树的高度差不超过1

二叉树的遍历方式:

前序遍历

从根节点开始,按照当前节点,左子结点,右子结点的顺序遍历。

中序遍历

从最左边的子节点开始,按照左子结点,当前节点,右子节点遍历。

后序遍历

从最左边的子节点开始,按照左子结点,右子节点遍历,当前节点的顺序遍历

层序遍历

从根节点开始一层一层的去遍历

平衡二叉树左旋

确定支点:从添加的结点开始,不断的往父节点找不平衡的节点

步骤:1.以不平衡的点作为支点

2.把支点左旋降级,变成左子节点

3.晋升原来的右子节点

左旋后=》

复杂情况:根节点为支点 

步骤:1.以不平衡的点作为支点

2.将根节点的右侧往左拉

3.原先的右子节点变成新的父节点,并把多余的左子结点让出给已经降级的根节点当右子节点

左旋后==》

右旋=》同左旋

需要旋转的四种情况

1.左左:当根节点左子树的左子树有节点插入,导致二叉树不平衡---》一次右旋

2.左右:当根节点左子树的右子树有节点插入,导致二叉树不平衡

 先局部左旋,再整体右旋

3.右右:当根节点右子树的右子树有节点插入,导致二叉树不平衡==》一次右旋

4.右左:当根节点右子树的左子树有节点插入,导致二叉树不平衡==》先局部右旋,再整体左旋

红黑树

是一种特殊的二叉查找树,红黑树的每一个节点上都有存储位表示节点的颜色

每个节点可以是红或者黑;红黑树不是高度平衡的,它的平衡是通过“红黑规则”进行实现的、

红黑规则:

数据结构(红黑树)添加节点的规则 

红黑树的增删改查性能都挺好,最浪费性能的是旋转,红黑树中旋转少。

Set集合

set集合的实现类

HashSet:无序、不重复、无索引

LinkedHashSet:有序、不重复、无索引

TreeSet:可排序、不重复、无索引

set接口中的方法上基本与collection的API一致

IDEA的快捷键

ctrl+alt+m 选择语句,按 会抽取成一个方法。

ctrl+b 跟进

ctrl +alt+左键 回到上一步

ctrl+n搜索类

alt+7罗列出类的大纲视图  或者ctrl+F12,还可以直接输入字母搜索

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion 模型:从噪声中生成逼真图像

你好&#xff0c;我是郭震 简介 Stable Diffusion 模型是一种生成式模型&#xff0c;可以从噪声中生成逼真的图像。它由 Google AI 研究人员于 2022 年提出&#xff0c;并迅速成为图像生成领域的热门模型。 数学基础 Stable Diffusion模型基于一种称为扩散概率模型(Diffusion P…

并查集算法

文章目录 并查集并查集引入1.初始化2.查询3.合并路径压缩代码模板(1)朴素并查集&#xff1a;(2)维护size的并查集&#xff1a;(3)维护到祖宗节点距离的并查集&#xff1a; 并查集 并查集引入 并查集&#xff08;Union-find Sets&#xff09;是一种非常精巧而实用的数据结构&a…

设计模式 -- 1:简单工厂模式

目录 代码记录代码部分 代码记录 设计模式的代码注意要运用到面向对象的思想 考虑到紧耦合和松耦合 把具体的操作类分开 不让其互相影响&#xff08;注意这点&#xff09; 下面是UML类图 代码部分 #include <iostream> #include <memory> // 引入智能指针的头文…

Redis底层核心对象RedisObject源码分析

文章目录 1. redis底层数据结构2. 插入KV底层源码流程分析 1. redis底层数据结构 redis 6数据结构和底层数据结构的关系 String类型本质是SDS动态字符串&#xff0c;即redis层面的数据结构底层会有对应的数据结构实现&#xff0c;上面是redis 6之前的实现 redis 7数据结构和底…

[MYSQL数据库]--表的增删查改和字段类型

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、表的增…

高数立体几何笔记

上个学期立体几何章节的一点笔记&#xff0c;很潦草&#xff0c;但重点内容基本都有复习到 Page1&#xff1a;介绍了向量的模、夹角、单位向量、投影投影向量、方向角、点乘、叉乘、混合积的基本运算和性质Page2: 回顾了高中所学的平面直线的多种表示方法以及距离的计算方法&…

【工作实践-07】uniapp关于单位rpx坑

问题&#xff1a;在浏览器页面退出登录按钮上“退出登录”字样消失&#xff0c;而在手机端页面正常;通过查看浏览器页面的HTML代码&#xff0c;发现有“退出登录”这几个字&#xff0c;只不过由于样式问题&#xff0c;这几个字被挤到看不见了。 样式代码中有一行为&#xff1a…

Midjourney绘图欣赏系列(十一)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

Linux常见指令总结

ls&#xff1a;显示当前目录下文件列表 常用的命令行参数&#xff1a; -l 显示更多的文件属性 -a 显示所有的文件/目录&#xff08;包括隐藏的&#xff09; -d 只显示目录 ps&#xff1a;参数可以叠加使用。 例如&#xff1a;ls -la 显示所有文件…

wait 和 notify方法

目录 1.1 wait()方法 wait 做的事情: wait 结束等待的条件: 1.2 notify()方法 1.3notifyAll方法 1.4wait()和sleep()对比 由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序. 完成这个协调…

重学SpringBoot3-日志Logging

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-日志Logging 引言默认日志配置日志门面如何实现默认配置 自定义日志配置日志级别日志分组日志格式日志输出自定义 Logback 配置切换日志框架 日志使用方…

数据结构 - 链表 (四)

这篇博客将介绍带头循环的双向链表&#xff0c;实现链表的头部插入/删除&#xff0c;尾部插入/删除&#xff0c;查找&#xff0c;以及任意位置的插入删除。 1.结构 带头循环的双向链表的结构如下图所示&#xff0c;一个结点内部包含数据&#xff0c;以及分别指向前一个以及后…

LabVIEW质谱仪开发与升级

LabVIEW质谱仪开发与升级 随着科技的发展和实验要求的提高&#xff0c;传统基于VB的质谱仪系统已经无法满足当前的高精度和高效率需求。这些系统通常存在着功能不全和操作复杂的问题&#xff0c;影响了科研和生产的进度。为了解决这些问题&#xff0c;开发了一套基于LabVIEW开…

16. C++标准库

C标准库兼容C语言标准函数库&#xff0c;可以在C标准库中直接使用C语言标准函数库文件&#xff0c;同时C标准库增加了自己的源代码文件&#xff0c;新增文件使用C编写&#xff0c;多数代码放在std命名空间中&#xff0c;所以连接C标准库文件后还需要 using namespace std;。 【…

Python算法题集_搜索旋转排序数组

Python算法题集_搜索旋转排序数组 题33&#xff1a;搜索旋转排序数组1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【二分法区间判断】2) 改进版一【二分找分界标准二分法】3) 改进版二【递归实现二分法】 4. 最优算法5. 相关资源 本文为Pytho…

【C++进阶】C++多态概念详解

C多态概念详解 一&#xff0c;多态概念二&#xff0c;多态的定义2.1 多态构成的条件2.2 什么是虚函数2.3 虚函数的重写2.3.1 虚函数重写的特例2.3.2 override和final 2.4 重载和重写&#xff08;覆盖&#xff09;和重定义&#xff08;隐藏&#xff09;的区别 三&#xff0c;抽象…

QGIS 开发之旅一《二次开发环境搭建》

1、 安装QT 下载QT Index of /new_archive/qt 我选择的版本是 Qt5.14.2 2、安装VS2017 Downloads & Keys - Visual Studio Subscriptions。下载后选择windows通用平台开发和C 开发就可以了。 3、安装插件QT vs tools 搜索 qt vs tools&#xff0c;选择第一个安装 …

Python合并两张图片 | 先叠透明度再合并 (附Demo)

目录 前言正文 前言 用在深度学习可增加噪音&#xff0c;增加数据集等 推荐阅读&#xff1a;Pytorch 图像增强 实现翻转裁剪色调等 附代码&#xff08;全&#xff09; 正文 使用Pillow库来处理图像&#xff08;以下两张图来自网络&#xff09; 图一&#xff1a; 图二&…

​FastIce-Tech 企业官网开源模版:专为中小企业设计的轻量级网址

标题&#xff1a;FastIce-Tech 企业官网开源模版&#xff1a;专为中小企业设计的轻量级网址 中小企业在建立企业官网时常常面临着时间、资源和技术的限制。为了解决这些问题&#xff0c;FastIce-Tech 企业官网开源模版应运而生。它是一个基于 Vue.js、ElementUI 和 Vue-Router …

(一)运行起自己的chatGPT

一、运行步骤 前面所有步骤可以参见https://datawhaler.feishu.cn/docx/BwjzdQPJRonFh8xeiSOcRUI3n8b 二、注意 需要注意的是&#xff1a; 部署起来后&#xff0c;必须使用域名访问才能进入。用ip地址端口访问不成功 三、运行效果 gradio需要额外配置一个外部端口&#x…