day18
静态内部类
packagecom.qf.test_01;
/**
* 看程序,写结果:
*
* 考点:
* 静态代码块,构造方法优先级
* static的特点:随着类的加载而加载
*/
classClassA{
static {
System.out.println("In ClassA Static"); //1)
}
publicClassA(){
System.out.println("ClassA()"); //2)
}
}
classClassB{
static {
System.out.println("In ClassB Static"); //4)
}
publicClassB(){
System.out.println("ClassB()"); //6)
}
}
classClassCextendsClassB{
static{
System.out.println("In ClassC Static"); //5)
}
publicClassC(){
System.out.println("ClassC()"); //7)
}
}
classMyClass {
//静态 实例变量--->当MyClass类在加载的时候,立即创建了静态实例ca--->ClassA
//实例变量 :不加静态
staticClassAca=newClassA();
//实例变量
ClassCcc=newClassC();
static{
System.out.println("In MyClass Static"); //3)
}
publicMyClass(){
System.out.println("MyClass()"); //8
}
}
publicclassTestMain{
publicstaticvoidmain(Stringargs[]){
MyClassmc1=newMyClass();
MyClassmc2=newMyClass();
System.out.println(mc1.cc==mc2.cc); //==连接是两个引用类型:比较地址值 false
}
}
常用类-object
packagecom.qf.object_01;
importcom.sun.xml.internal.ws.addressing.WsaActionUtil;
/**
* 常用类以及后面高级特性:集合框架,多线程,io流,网络编程,反射等等都是使用jdk提供API
*
* API:Application Programming Interface:应用程序接口文档
* 需要将重点的类的重点功能--记住
* 举例:String类的拆分/将字符串转换成字符数组等等
* java.lang.Object类:所有的类父类(包括自定义的类)
* 重点功能:
* public final Class getClass():获取正在运行的类; (返回字节码文件对象) (跟后面反射有关系)
*
*
*
* 面试题:
* 在Java中获取一个类的字节码文件对象的方式有几种?
* 有三种:
* 1)public final Class getClass():获取正在运行的类; (返回字节码文件对象)
* 2)在Java中任意类型的class属性 举例: Class c = 类名.class
* 3)Class类提供的一个静态方法
* public static Class forName(String classPathName) :参数为当前类的全限定名称
*/
publicclassObjectDemo {
publicstaticvoidmain(String[] args) throwsClassNotFoundException {
//创建两个学生对象
Students1=newStudent() ;
Students2=newStudent() ;
//public final Class getClass():获取正在运行的类; (返回字节码文件对象)
Classc1=s1.getClass() ;
System.out.println(c1) ;//class com.qf.object_01.Student (class标记类 包名.类名-->类的全限定名称)
Classc2=s2.getClass() ;
System.out.println(c2) ;
System.out.println(c1==c2) ;//true:s1和s2都是com.qf.object_01.Student:类就加载一次,对象可以不断new!
System.out.println("------------------------------------------") ;
//在Java中任意类型的class属性:也可以获取到一个类的字节码文件!
Classc3=Student.class ;
System.out.println(c3) ;
System.out.println(c3==c2);
System.out.println("-----------------------------------------") ;
//第三种获取字节码文件方式:Java提供Class类---跟反射相关的-提供静态功能-->返回值是它自己本身
//public static Class forName(String className) throws ClassNotFoundException
//这个方法在使用过程中,可能出现类找不到异常,谁调用这个方法,必须对这个异常处理---给上面抛出
//这个方法的参数需要传递的是当前类的"全限定名称"
// Class c4 = Class.forName("Student") ;//这里必须是全限定名称
Classc4=Class.forName("com.qf.object_01.Student") ;
System.out.println(c4) ;
System.out.println(c4==c3);
}
}
packagecom.qf.object_01;
/**
* 学生类
*/
//public class Student extends Object{
publicclassStudent {//所有类的默认继承Object
}
toString
packagecom.qf.object_02;
/**
*Object类的toString()
* public String toString():返回对象的字符串表示形式。
* 结果应该是一个简明扼要的表达,容易让人阅读。 建议所有子类覆盖此方法(否则,打印出来的是地址值!)
*
*
*
* public int hashCode():返回对象的哈希码值,不同的对象,它的哈希码值不同
* (理解为 "地址值",它不是实际意义的地址值----通过哈希算法算出来的)
*/
publicclassObjectDemo {
publicstaticvoidmain(String[] args) {
// System.out.println("helloworld".hashCode());
// System.out.println("hello".hashCode());
//通过有参方法来创建Teacher类对象
Teachert=newTeacher("高圆圆",44) ;
System.out.println(t) ;//直接输出对象名等价于---Object类的toString()
System.out.println(t.toString());
System.out.println("---------------------------------------");
//Class c = t.getClass() ;
//System.out.println(c) ;//class com.qf.object_02.Teacher --->Class类的ublic String getName() :获取类的全限定名称
//String name = c.getName();
//System.out.println(name);
// int i = t.hashCode();
//System.out.println(i);
//Integer.toHexString(整数类型):将整数类型---转成十六进制数据,并且以字符串形式体现
/*String str = Integer.toHexString(t.hashCode());
System.out.println(name+"@"+str) */;
//上面代码没有意义,建议所有子类都覆盖这个方法:
}
}
/**
* 任何类都继承Object类---toString方法源码
* public String toString() {
* return getClass().getName() + "@" + Integer.toHexString(hashCode());
*
* //return this.getClass().getName() +"@" +Integer.Integer.toHexString(this.hashCode())
* }
*/
packagecom.qf.object_02;
/**
* 定义一个Teacher类
*/
//public class Teacher extends Object {
publicclassTeacher {//默认继承Object类
privateStringname ; //姓名
privateintage ; //年龄
public Teacher(){}
publicTeacher(Stringname,intage){
this.name=name ;
this.age=age ;
}
/* public String toString(){
return "姓名是:"+name+",年龄是:"+age;
}*/
//idea生成
@Override
publicStringtoString() {
return"Teacher{"+
"name='"+name+'\''+
", age="+age+
'}';
}
}
equals方法
packagecom.qf.object_03;
/**
* public boolean equals(Object obj)指示一些其他对象是否相等。
*
* 面试题:
* ==和equals的区别?
*
* ==连接的是两个基本数据类型:比较的数据值是否相同
* 而如果引用类型,比较的是引用类型的地址值是否相等!
*
* equals:Object的equaels方法默认比较的是两个对象的地址值相同,
* 如果你要比较成员信息的内容是否相同,必须重写Object的equals方法以及hashCode,重写之后比较的是内容是否相同(成员信息)
*
* equals重写之后,是比较里面的每一个成员信息是否一样,如果都一样;
* 还有比较两个成员对应的hashCode是否一样,如果一样,是同一个人!
*
*
*
*/
publicclassObjectDemo3 {
publicstaticvoidmain(String[] args) {
inta =20 ;
intb=20 ;
System.out.println(a==b) ;//连
System.out.println("---------------------------------------------------") ;
Students1=newStudent() ;
Students2=newStudent() ;
System.out.println(s1==s2) ;
System.out.println("----------------------------------------------------") ;
Students3=newStudent("高圆圆",33) ;
Students4=newStudent("高圆圆",33) ;
System.out.println(s3==s4);//false
// public boolean equals(Object obj)指示一些其他对象是否相等。
//idea生成了equals和hashCode
System.out.println(s3.equals(s4));
}
}
/**
* 查看一下Object类的equals的源码:
* public boolean equals(Object obj) { //s3.equals(s4)
* return (this == obj); //return s3 == s4; 默认地址值是否相同
* }
*/
packagecom.qf.object_03;
/**
* 学生类
*/
publicclassStudent {
privateStringname ;
privateintage ;
publicStudent(){}
publicStudent(Stringname,intage){
this.name=name ;
this.age=age ;
}
//alt+ins---->toString:重写Object的toString方法
@Override
publicStringtoString() {
return"Student{"+
"name='"+name+'\''+
", age="+age+
'}';
}
//alt+ins---->equals and hashcode
@Override
publicbooleanequals(Objecto) { //s3.equals(4)
if (this==o) returntrue; /*
if(s3==s4){
return true ;
}
*/
if (o==null||getClass() !=o.getClass()) /*
if(s4==null || s3.getClass()!=s4.getClass)){
return false ;
}
*/
returnfalse;
Studentstudent= (Student) o; //向下转型:
if (age!=student.age) returnfalse; //if(this.age !=student.age)
returnname.equals(student.name); //return s3.name.equals(student.name) :name类型的String
//String类型重写Object的equals()--->比较两个姓名的内容是否相同
}
@Override
publicinthashCode() {
intresult=name.hashCode(); //int reuslt = "高圆圆".hashCode() ;
result=31*result+age; //result = 31 *result +33
returnresult; //固定的值
}
}
object的clone方法
packagecom.qf.object_04;
/**
* Object的克隆方法:创建并返回此对象的"副本"----前提是自定义的类型必须实现Cloneable接口,否则无法克隆!
* protected Object clone() throws CloneNotSupportedException
*
*/
publicclassObjectDemo4 {
publicstaticvoidmain(String[] args) throwsCloneNotSupportedException {
//创建一个学生对象
//没有学习克隆之前
Students1=newStudent() ;
s1.name="高圆圆" ;
s1.age=44 ;
System.out.println(s1);
System.out.println("---------------------------") ;
//定义一个Student类型的变量s2,将s1赋值给s2
Students2=s1 ; //将堆内存地址值给它
System.out.println(s2) ;
System.out.println("------------使用Object类的clone方法------------------") ;
//s1.clone() ;//次对象的类必须实现接口Cloneable ,才能进行克隆!
//可以克隆了,实现接口了
//protected Object clone() throws CloneNotSupportedException
Objecto=s1.clone(); // 相当于向上转型:
//将强转为子类型:向下转型
Students3= (Student) o;
System.out.println(s3);
}
}
packagecom.qf.object_04;
/**
* 学生类
*/
//这个类必须实现接口Cloneable ,才能克隆
/**
* 如果一个接口没有成员变量,连成员方法都没有,将这类接口称为"标记接口"
* Cloneable接口:某个类如果能够实现这个接口,那么这个类对象就可以克隆!
*/
publicclassStudentimplementsCloneable{
Stringname ;
intage ;
@Override
publicStringtoString() {
return"Student{"+
"name='"+name+'\''+
", age="+age+
'}';
}
//重写clone方法
@Override
protectedObjectclone() throwsCloneNotSupportedException {
returnsuper.clone();
}
/**
* Object类的clone方法里面被 native:本地方法---非Java语言实现
* protected native Object clone() throws CloneNotSupportedException;
*
*
* JNI:Java Native Interface:Java本地接口---通过java语言调用底层语言C
*/
}
Object类的垃圾回收方法
packagecom.qf.object_05;
/**
* Object类的垃圾回收方法
* protected void finalize()throws Throwable--跟gc垃圾回收器有关系
* 当jvm开启垃圾回收器的时候,就会回收堆内存中没有更多引用的对象(new 出来的东西)
*
* 当前垃圾回收器开始运行,会调用Object类的finalize()方法,来回收对象,子类重写了,会调用子类的finalize方法
*
*/
publicclassObjectDemo5 {
publicstaticvoidmain(String[] args) {
//创建一个人类
Personp=newPerson("高圆圆",44) ;
System.out.println(p) ;
System.out.println("--------------------------") ;
p=null ; //堆内存没有东西了
//System类--->public static void gc()运行垃圾回收器
// 手动开启垃圾回收器 (java语言中自动回收)---jvm垃圾回收--是一个线程(垃圾回收线程)
System.gc();
}
}
/**
* Object的finalize方法的原码:
* protected void finalize() throws Throwable { }
*
*/
package com.qf.object_05;
/**
* 人类
*/
public class Person {
private String name ; //姓名
private int age ; //年龄
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//重写finalize方法:
@Override
protected void finalize() throws Throwable {
System.out.println("正在回收没有更多引用的对象:"+this);
}
}
java.util.Scanner:文本扫描器(键盘录入数据的)
package com.qf.scanner_06;
import java.io.InputStream;
import java.util.Scanner;
/**
* java.util.Scanner:文本扫描器(键盘录入数据的)
* 构造方法:
* public Scanner(InputStream source):
* 创建一个文本扫描器对象,里面参数是字节输入流,读取键盘录入的一些数据
*
* 成员方法:
*
* 获取功能:除过不能录入char类型之外.都可以录入!
* int nextInt():录入int类型
* String next():录入字符串
* String nextLine():录入一行字符串
* ....
* 判断功能
* boolean hasNextXXX()方法:判断下一个录入的是为XXX类型
*
*
* 细节:
* 如果先录入int,在录入String,在录入String(使用String nextLine())---String的值会被漏掉;
* 解决方案:
* 1)使用String next():录入单个字符串(推荐)
* 2)在使用nextLine()之前,重新创建一个新的Scanner对象;
*
*
* 需求:
* 键盘录入5个学生的语文成绩,数学成绩,英语成绩,姓名---对学生成绩排序
* int chinses;
*
* int math;
* int english;
* String name ;
*
* //全部录入的时候---全部都使用String录入的 --->将 语文成绩,学生成绩/英语成绩---数字字符串--->转换int
* "98" 数字字符串---->98 int
*
* 开发中:类型转换
* 需求的结果可能是A类型,但是中间的业务过程,可能需要B类类型的功能,将A类型---B类型;
* 使用完功能之后,再B类型---转换A类型!
*
*
*/
public class ScannerDemo {
public static void main(String[] args) {
//创建键盘录入对象
//Scanner sc = new Scanner(System.in) ;
//等价于
//System类---提供静态变量:in--而且是一个常量
//public static final InputStream in
InputStream in = System.in ; //InputStream:io流里面:后面讲
// public Scanner(InputStream source):
Scanner sc = new Scanner(in) ;
//提示并录入数据
System.out.println("请您输入一个数据:");
//现在录入一个int
//int a = sc.nextInt() ;//java.util.InputMismatchException:输入类型不匹配 :接收结果类型和录入的类型不匹配
//boolean hasNextXXX方法():判断下一个录入的是为XXX类型
if(sc.hasNextInt()){//如果下一个录入的是int类型
int a = sc.nextInt() ;
System.out.println(a);
}else if(sc.hasNextLine()){ //录入的下一个是String类型
String s = sc.nextLine() ;
System.out.println(s);
}else{
System.out.println("没有这个类型");
}
//System.out.println(a) ;
}
}
String类
String类
package com.qf.string_07;
import com.sun.xml.internal.ws.addressing.WsaActionUtil;
/**
* String类:代表字符串,是一个常量,创建之后,其值不能更改!
* 举例:
* String s = "abc" ; 格式 开发中定义字符串就这个格式!
* 字符串的底层就是一个字符数组组成!char[]--->String
*
* 构造方法:
* public String():创建字符串对象
* public String(String original):将指定的字符串传进去,构造一个字符串对象
* public String(char[] value):将字符串数组---构造成String
* public String(char[] value,int offset,int count):将一部分字符数组转换成String
* public String(byte[] bytes)将字节数组---构造成String
* public String(byte[] bytes, int offset,int length):将一部分字节数组---构造成String
*
* 如果存在类型转换问题:
* 已知char[]--->String public String(char[] value)
* 已知byte[]--->String public String(byte[] bytes)
*
* 如果仅仅表示定义一个String对象---推荐的格式
* String 变量名 = "字符串常量" ;
*
*
*
*/
public class StringDemo {
public static void main(String[] args) {
// public String():创建字符串对象
String s = new String() ;
System.out.println("s:"+s) ;//打印不是地址,而空字符串,String类重写了Object类的toString()
System.out.println("----------------------------------------");
// public String(String original):将指定的字符串传进去,构造一个字符串对象
String s2 = new String("hello") ;
System.out.println("s2:"+s2) ;
System.out.println("---------------------------------------------") ;
//public String(char[] value):将字符串数组---构造成String
char[] chs = {'高','圆','圆'} ;
String s3 = new String(chs) ;
System.out.println("s3:"+s3) ;
System.out.println("----------------------------") ;
//public String(char[] value,int offset,int count):将一部分字符数组转换成String
String s4 = new String(chs,1,2) ;
System.out.println("s4:"+s4);
System.out.println("-------------------------------");
// public String(byte[] bytes)将字节数组---构造成String :
byte[] bytes = {97,98,99,100,101} ;
String s5 = new String(bytes) ;//转换过程,将每一个数据找ASII码表对应的字符值,构造成字符串
System.out.println("s5:"+s5) ;//abcde
System.out.println("--------------------------------") ;
// public String(byte[] bytes, int offset,int length)
String s6 = new String(bytes,2,3) ;
System.out.println("s6:"+s6) ;
}
}
string面试题
package com.qf.string_07;
/**
* 面试题:
* s1和s2有什么区别?
* String s1 = "hello" ;
* String s2 = new String("hello") ;
*
* 第一个格式:
* 创建一个对象,直接在常量池中创建;
* 第二个格式:
* 需要在堆内存开辟空间,而且指向常量池地址:内存创建了两个对象!
*
* 两个都是创建字符串实例,但是推荐第一种,从内存角度考虑,消耗内存资源不严重!
*/
public class StringDemo2 {
public static void main(String[] args) {
String s1 = "hello" ;
String s2 = new String("hello") ;
System.out.println(s1==s2) ;//false 地址值相同
System.out.println(s1.equals(s2)) ; //true(String重写了Object的equals方法,比较内容是否相同)
}
}
面试题二
package com.qf.string_07;
/**
* 看程序,写结结果
*
* 考点:
* ==和equals的区别:
*
* ==:连接的是两个引用类型的数据,比较的是两个对象的地址是否相同
* Object的equals():默认比较的是两个对象的地址值是否相同,子类重写了equals(),就比较两个对象的内容是否相同
*
* 字符串常量相加:
* 先相加,然后看结果,是否在常量池中,如果有,直接返回值地址;否则开空间
* 字符变量相加:
* 先在常量池开辟空间,然后在操作;
*
*/
public class StringDemo3 {
public static void main(String[] args) {
String s1 = "hello" ;
String s2 = "world" ;
String s3 = "helloworld" ;
System.out.println((s1+s2)==s3) ;
System.out.println((s1+s2).equals(s3)) ;//String类重写了Object的equals方法,只管字符串内容是否一样
System.out.println("----------------------------") ;
System.out.println(("hello"+"world")==s3) ;//常量先相加,然后常量池中找,存在返回地址;否则常量池开空间
System.out.println(("hello"+"world").equals(s3)) ;//比较内容是否相同
}
}
String类中常用的功能
package com.qf.string_07;
/**
*String类中常用的获取功能:
* 1)public char charAt(int index) 获取指定索引值对应的字符
* 2)public int length() :字符串特有功能:获取字符串长度
*
* 3)public String concat(String str):拼接功能 将指定的字符串拼接到该字符串末尾,获取新的字符串
*
* 4)public int indexOf(String str)返回指定字符串第一次出现索引值
* public int lastIndexOf(String str):返回指定子字符串最后一次出现的索引值
*
*
* 5)public String[] split(String regex):字符串拆分功能
*
* 6)截取功能
* public String substring(int beginIndex,int endIndex)
* 从指定位置开始,截取到endIndex-1处结束,包前不包后
* public String substring(int beginIndex)
* 从指定位置开始默认截取到末尾!
*
*/
public class StringDemo4 {
public static void main(String[] args) {
String s = "helloworld" ;
//public char charAt(int index) 获取指定索引值对应的字符
/*char ch = s.charAt(0) ;
System.out.println(ch);
System.out.println(s.charAt(1));
System.out.println(s.charAt(2));
System.out.println(s.charAt(3));
System.out.println(s.charAt(4));
System.out.println(s.charAt(5));
System.out.println(s.charAt(6));*/
//System.out.println(s.length());
//charAt(int index)+length()可以遍历字符串
for(int x = 0 ; x < s.length(); x++){
char ch = s.charAt(x) ;//获取指定索引值对应的字符
System.out.print(ch+"\t");
}
System.out.println();
System.out.println("---------------------------------------------");
//public String concat(String str):拼接功能 将指定的字符串拼接到该字符串末尾,获取新的字符串
//传统的字符串拼接+
System.out.println("hello"+10);
System.out.println(100+"name"+"is"+"hello");
String str = s.concat("高圆圆");
System.out.println(str);
System.out.println("---------------------------------------------");
//public int indexOf(String str)返回指定字符串第一次出现索引值
System.out.println(s.indexOf("o"));
System.out.println(s.lastIndexOf("o"));
System.out.println("---------------------------------------------------------") ;
//public String[] split(String regex) :拆分
String s2 = "Java-Python-C-Golang-R-Hadoop" ;
String[] strArray = s2.split("-"); //字符串数组
//遍历字符串数组
for(int x = 0 ; x < strArray.length ; x++){
System.out.print(strArray[x] +"\t");
}
System.out.println();
System.out.println("--------------------------------------------------------------");
/**
* public String substring(int beginIndex,int endIndex)
* 从指定位置开始,截取到endIndex-1处结束,包前不包后
* public String substring(int beginIndex)
* 从指定位置开始默认截取到末尾!
*/
String ss = s.substring(5, 8);
System.out.println(ss);
System.out.println(s.substring(5));
}
}
String类的常用的转换功能
package com.qf.string_07;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* String类的常用的转换功能
* public byte[] getBytes(): 将字符串转换成字节数组 (编码过程:将能看懂的东西--->变成看不懂的!)
* (使用平台默认字符集)
*
* public char[] toCharArray() :将字符串转换成字符数组 (使用居多)
*
* public static String valueOf(常见的基本类型int/long/double/float/boolean/Object):
* String的万能方法:将上面的常用类型--转换成String
*
* public String toUpperCase():将指定字符串转换成大写
* public String toLowerCase():将指定字符串转换成小写
*/
public class StringDemo5 {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "中国" ;
//public byte[] getBytes(): 将字符串转换成字节数组 (编码过程:将能看懂的东西--->变成看不懂的!)
//idea设置的平台字符集:utf-8:一个中文三个字节
byte[] bytes = s.getBytes() ;
//System.out.println(bytes) ;
//将数组---转换成String--->Arrays数组工具类 toString(任意类型数组)
System.out.println(Arrays.toString(bytes));
System.out.println("---------------------------------") ;
//今天上午:String(byte[] byte) :解码--->将卡不懂的字节---变成看懂的字符串 (默认字符集utf-8)
String str = new String(bytes) ;//使用指定gbk格式进行解码 或者默认字符集进行解码
System.out.println(str) ;
System.out.println("------------------------------------------") ;
String ss = "helloJavaEE" ;
//public char[] toCharArray():将字符串转换成字符数组
char[] chs = ss.toCharArray();
//遍历字符数组
for(int x = 0 ; x < chs.length ; x++){
char ch = chs[x] ; //接收每一个字符
System.out.print(ch+"\t");
}
System.out.println();
System.out.println("---------------------------------------------------") ;
int i = 100 ;
System.out.println(i) ; //i是int类型
String result = String.valueOf(i);
System.out.println(result);//"100" 数字字符串
System.out.println("--------------------------------------------------") ;
System.out.println(ss.toLowerCase());
System.out.println(ss.toUpperCase());
}
}
键盘录入一个字符串,将字符串的第一个字符转换成小写,其余字符转换成大写
package com.qf.string_07;
import java.util.Scanner;
/**
* 需求:
* 键盘录入一个字符串,将字符串的第一个字符转换成小写,其余字符转换成大写(不考虑特殊字符)
* 举例:
* "Helloworld"---->"hELLOWORLD"
*
* 分析:
* 1)创建键盘录入对象
* 2)将字符串的第一个字符,截取出来 substring(0,1)--->将截取后的字符---转换成大写
* 3)从第二个字符开始,截取出来 substring(1)--->将截取后的字符串---转换小写
* 4)将2)和4)拼接----concat(指定的字符串)
*
*
*
*/
public class StringTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入字符串
System.out.println("请输入一个字符串:") ;
String line = sc.nextLine() ;
/*//1)先将line的第一个字符截取出来
String s1 = line.substring(0,1) ;
//2)将s1--->转换成大写
String s2 = s1.toUpperCase() ;
//3)将line字符串 从第二个字符开始截取出来
String s3 = line.substring(1) ;
//4)将s3-->转换成小写
String s4 = s3.toLowerCase() ;
//5)将s2和s4拼接---String的concat拼接功能
String result = s2.concat(s4) */;
// System.out.println(result) ;
//一步走 :链式编程
String result =
line.substring(0,1).toUpperCase().concat(line.substring(1).toLowerCase()) ;
System.out.println(result);
System.out.println("--------------------------------------");
//调用方法
String result2 = getStr(line) ;
System.out.println(result2);
}
public static String getStr(String s){
return
s.substring(0,1).toUpperCase().concat(s.substring(1).toLowerCase()) ;
}
}
已知数组静态初始化的,int[] arr = {24,57,69,13,98} ;
定义功能,将数组转换成String --->把数组遍历出来--->每一个元素拼接成String[元素1, 元素2, 元素3, ....] (不允许使用Arrays工具类的toString(数组对象))
package com.qf.string_07;
/**
* 需求:
* 已知数组静态初始化的
* int[] arr = {24,57,69,13,98} ;
* 定义功能,将数组转换成String --->把数组遍历出来--->每一个元素拼接成String
* [元素1, 元素2, 元素3, ....] (不允许使用Arrays工具类的toString(数组对象))
*/
public class StringTest2 {
public static void main(String[] args) {
//已知数组
int[] arr = {24,57,69,13,98} ;
//调用将数组转换String的方法
String result = arrayToString(arr) ;
System.out.println(result) ;
}
//将转换成String
public static String arrayToString(int[] array){
//定义一个最终结果变量
String s = "" ;
s += "[" ;//或者使用字符串的concat功能
//遍历数组
for(int x = 0 ; x < array.length ; x++){
if(x==array.length-1){
//最后一个元素
s+=array[x] +"]" ;
}else{
//中间元素
s+= array[x] +", ";
}
}
return s ;
}
}
String类判断功能以及其他功能:
package com.qf.string_08;
/**
* String类判断功能以及其他功能:
* public boolean constains(String str):判断大串中是否包指定的子字符串
* public boolean equals(Object anObject)):比较两个字符串内容是否相同
* public boolean equalsIgnoreCase(String anotherString)):忽略大小写比较
* public boolean startsWith(String prefix):字符串是否以指定的前缀开头
* public boolean endsWith(String str):字符串是否以指定的后缀结尾
*
* 其他功能:
* public String replace(char oldChar,char newChar)替换功能:使用指定的新的字符替换以前的字符
* public String trim():删除前后两端空格
*
* 应用场景:trim(): 使用io(intput输入 Output输出)流进行 读写复制(文件内容在网络中传输)
* 文件内容前后有一些空字符出现,获取到文件内容之后,先去trim()去除两端空格
*
*
*
*
*/
public class StringDemo {
public static void main(String[] args) {
String s = "helloworldJavaEE" ;
System.out.println(s.contains("owo"));
System.out.println(s.contains("ak47"));
System.out.println("-----------------------------");
System.out.println(s.equals("HelloworldJavaEE"));//区分大小写
System.out.println(s.equalsIgnoreCase("HelloworldJavaEE"));
System.out.println("--------------------------------") ;
System.out.println(s.startsWith("hel"));
System.out.println(s.endsWith("EE"));
System.out.println("---------------------------------") ;
//public String replace(char oldChar,char newChar)替换功能:使用指定的新的字符替换以前的字符
System.out.println(s.replace('l','*'));
System.out.println("------------------------------------") ;
String s1 = " hello ";
System.out.println("s1--->"+s1) ;
String s2 = s1.trim() ;
System.out.println("s2--->"+s2) ;
}
}
面试题
package com.qf.string_08;
/**
* 面试题:
* String s1 = "hello" ;
* String s2 = "hel" ;
* 这个两个字符串按照字典顺序比较结果是怎么计算的?
*
* --->两个字符串--->底层是以字符数组存储-获取字符数组长度,获取长度的最小值
* 使用最小值作为 while循环条件, 如果没有取到最小值,一直循环,
* 循环逻辑:
* 通过获取两个字符数组的每一个字符,如果都相同,最终临界条件达到 ,两个字符数组长度相减
*
* 如果获取到字符,如果两个字符不相等,直接是两个字符---对应的ASCII码表的值相减---直接得到字典顺序的值!
*/
public class StringTest {
public static void main(String[] args) {
String s1 = "hello" ;
String s2 = "hel" ;
//public int compareTo(String another)
System.out.println(s1.compareTo(s2)) ;
System.out.println("-----------------------------") ;
String s3 = "abc" ;
int i = s1.compareTo(s3);
System.out.println(i);
}
}
class Demo{
private final void m1(){
}
}
day19
晨写-今日内容
#晨写
##1.列举出Object类中常用的方法
```java
publicbooleanequals(ObjectanoterObj):判断两个引用数据是否相等----底层原码this==anoterObj (几乎常见的类都会重写Object类的equals和hashCode(),两个对象的内容(成员信息)是否相等)
publicStringtoString() //打印出对应的字符串形式,引用类型中,直接输出对象名称等价于调用了Object的toString-->打印出地址值 (建议所有子类都覆盖这个方法,结果是一个让人阅读的表达式!)
protectedObjectclone() throwsCloneNOtSupportedException// 创建对象的副本 (克隆方法)
//前提要克隆,当前这个对象所在的类型必须实现一个 "标记接口" Cloneable接口,才能够完成克隆
publicinthashCode() //哈希码值---->每一个不同的对象它的哈希码值不同的,可以理解为"地址值"---
->//hash算法---返回值int类型的取值范围的值 (在引用数据类型中和equals一块要被重写)
```
##2.String类的特点是什么?
```markdown
String是一个不可变的,一旦被创建,其值不能被更改!(常量池中地址);
创建字符串格式:
Strings="字符串" ; //推荐
Strings=newString("字符串") ;
String类特殊的引用类型,它作为方法形式参数,形式参是改变不会影响实际参数(和基本类型一致)
```
```java
classDemo{
publicstaticvoidmain(String[] args){
Strings="helloworld" ;
System.out.println(s) ;
change(s) ;
System.out.println(s) ;//helloworld
}
publicstaticvoidchange(Stringstr){//形式参数是一个String类型
str+="javaee" ;
System.out.println(str) ;//helloworldjavaee
}
}
```
##3.列举出String类的转换功能有哪些?(4个)
```java
publicchar[] toCharArray() //将字符串转换成字符数组
publicbyte[] getBytes() //使用平台的默认字符集对字符串进行编码---字节数组
publicstaticStringvalueOf(int/Object/double/float/boolean......)//将指定的类型转换String
publicStringtoUppercase() //将字符串转换成大写
publicStringtoLowercase() //将字符串转换成小写
...
```
##4.列举出String类的获取功能(4个)
```java
//截取功能
publicStringsubstring(intbeginIndex,intendIndex)//从指定位置开始截取到endIndex-1处结束
publicStringsubstring(intbeiginIndex)//从指定位置开始默认截取到末尾
//拆分
publicString[] spilt(Stringregex)//将一个字符串通过指定分隔号拆分成字符串数组
//拼接功能
publicStringconcat(StringanotherString)//使用当前字符串和指定的字符串拼接成一个新的字符串,在末尾拼接
//获取字符串长度
publicintlength()
//面试题:
数组中有没有length(),String类中length(),在集合中有没有length()?
数组中length属性,
String类中有length(),获取字符串长度
集合中没有,size():获取集合中元素数
```
##5.String类中两个字符串按照字典顺序如何比较的?
```markdown
//1)获取两个字符串对应的字符数组的长度
//2)获取最小值 Math.min(长度1,长度2);
//3)将两个字符串使用字符数组表示
//4)定义统计变量 k=0
//5)循环 条件 k < 两个长度最小值
//6) 不断的通过k=0,1,2....取出对应字符数组中的元素,如果都一致,最终条件不满足了
如果条件满足:如果某一个字符不一致,直接返回return第一个字符数组某一个字符-第二个字符数组某个字符
对应的ASCII码表的值相减
//7)return 长度1-长度2;
Strings1="abc" ;
Strings2="hel" ;
s1.compareTo(s2) ---->'a'-'h' =97-104
```
----
-----
#今日内容
##1.考试相关的编程题以及作业
##2.StringBuffer字符串缓冲区(容器)
##3.java.util.Date:日期类
```
重点:
java.util.Date日期格式和String日期文本格式相互转换
String日期文本 2022/10/01 2022年10月1日 2022-10-01 "字符串日期"
```
##4.Integer以及Character类的功能
```
Integeri=整数;---->底层的Integer.valueOf(整数)
Integer类----内部类---IntegetCache:内部缓存区: 缓存池大小-128~127
Character类提供
判断功能:判断一个字符是否为大写字母/小写字母/数字字符
```
##5.一些其他类
```
System类
Math类
Random类
BigDecimal类:小数精确计算
Calendar日历类....
```
##6.什么是对象数组?
```
使用一个数组存储5个学生?,学生有姓名,年龄,让遍历数组---展示学生的信息
创建数组
数据类型[] 数组名称=new数据类型[数组长度] ;
Student[] students=newStudent[5] ;
数组的弊端是长度固定,不支持长度可变的需求---->集合!
```
考试题-女人的宠物
packagecom.qf.test_01;
/**
* 动物类
*/
publicabstractclassAnimal {
privateStringname ;//动物名称
publicAnimal() {
}
publicAnimal(Stringname) {
this.name=name;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name=name;
}
//象方法enjoy()表示动物高兴时动作
publicabstract voidenjoy() ;
}
packagecom.qf.test_01;
/**
* 定义Cat类继承于Animal类,其中包括属性eyesColor,相关构造方法,
* 同时具体化父类中的抽象方法。
*/
publicclassCatextends Animal {
privateStringeyesColor ;
publicCat(StringeyesColor) {
this.eyesColor=eyesColor;
}
publicCat(Stringname, StringeyesColor) {
super(name);
this.eyesColor=eyesColor;
}
publicStringgetEyesColor() {
returneyesColor;
}
publicvoidsetEyesColor(StringeyesColor) {
this.eyesColor=eyesColor;
}
//重写父类的enjoy方法
@Override
publicvoidenjoy() {
System.out.println("养了一只猫,让猫笑一笑");
}
}
packagecom.qf.test_01;
/**
* 定义Dog类继承于Animal类,其中包括属性furColor,
* 相关构造方法,同时具体化父类中的抽象方法.
*/
publicclassDog extendsAnimal{
private StringfurColor ;
publicDog(StringfurColor) {
this.furColor=furColor;
}
publicDog(Stringname, StringfurColor) {
super(name);
this.furColor=furColor;
}
publicStringgetFurColor() {
returnfurColor;
}
publicvoidsetFurColor(StringfurColor) {
this.furColor=furColor;
}
//enjoy
@Override
publicvoidenjoy() {
System.out.println("养了一只狗,让狗叫一叫");
}
}
packagecom.qf.test_01;
/**
*女士类
*
* 中包括属性name
* ,以及Animal 类型的属性pet表示女士所养的宠物,定义构造方法,生成女士对象时初始化姓名和她所养的宠物。
*/
publicclassLady {
privateStringname ; //女士的名字
privateAnimalpet ; //宠物
publicLady() {
}
publicLady(Stringname, Animalpet) {
this.name=name;
this.pet=pet;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name=name;
}
publicAnimalgetPet() {
returnpet;
}
publicvoidsetPet(Animalpet) {
this.pet=pet;
}
//定义一个方法:myPetEnjoy表示此女士的宠物在高兴时的动作
publicvoidmyPetEnjoy(Animalp){//方法的形式参数一个抽象类
if(petinstanceof Cat){
Catc= (Cat)pet;
System.out.println(name+"养了一只"+pet.getName()+",眼睛颜色是:"+c.getEyesColor());
pet.enjoy();
}elseif(petinstanceof Dog){
Dogd= (Dog) pet;
System.out.println(name+"养了一只"+pet.getName()+",肤色是:"+d.getFurColor());
pet.enjoy();
}else{
System.out.println("没有提供这个宠物!");
}
}
/*public void show(Animal pet){
}*/
}
packagecom.qf.test_01;
/**
* 1)定义一个抽象类Animal,其中包括属性name,
* 相关构造方法,抽象方法enjoy()表示动物高兴时动作
* 2)定义Cat类继承于Animal类,其中包括属性eyesColor,相关构造方法,
* 同时具体化父类中的抽象方法。
* 3)定义Dog类继承于Animal类,其中包括属性furColor,
* 相关构造方法,同时具体化父类中的抽象方法.
*
* 4)定义Lady类,其中包括属性name,以及Animal 类型的属性pet表示女士所养的宠物,定义构造方法,
* 生成女士对象时初始化姓名和她所养的宠物。
* 定义一个方法:myPetEnjoy表示此女士的宠物在高兴时的动作。
* 提示:对于此类的定义中需要使用到多态性。
* 5)定义测试类。
* 创建一个张女士,养了一只猫,让这只猫笑一笑
*
* 创建一个王女士,养了一只狗,让这只狗叫一叫
*/
publicclassTest1 {
publicstaticvoidmain(String[] args) {
//创建一个张女士,养了一只猫,让这只猫笑一笑
Ladylady=newLady() ;
lady.setName("张女士") ;
lady.setPet(newCat("哆啦A梦","蓝色"));
lady.myPetEnjoy(newCat("哆啦A梦","蓝色"));
}
}
作业-用户登录+猜数字游戏
packagecom.qf.test_02;
importjava.util.Scanner;
/**
* 已知String usename = "admin";
* String password= "admin" ;
* 上面已知的是用户名和密码,现在给3次机会,键盘录入用户名和密码,与已知的用户名和密码进行匹配
* 如果3次机会用完,提示"您的电脑被锁住了,请联系管理员";如果三次机会没有用完,提示 "还剩多少次次机会"
* 如果一致,提示"恭喜您,登录成功"-----登录成功,可以开始玩猜数字游戏了...
*/
//测试类
publicclassTest2 {
publicstaticvoidmain(String[] args) {
//已知的用户名和密码
Stringusername="admin" ;
Stringpassword="admin" ;
//给三次机会---明确循环次数:使用for循环
for(intx=0 ; x<3 ; x++){//0,1,2
//创建键盘录入对象
Scannersc=newScanner(System.in) ;
//提示并录入数据
System.out.println("请您输入用户名: ") ;
Stringname=sc.nextLine() ;
System.out.println("请您输入密码:" ) ;
Stringpwd=sc.nextLine() ;
//已知的用户名和录入的用户名一致 并且 已知的密码和录入的密码一致 同时成立,才能登录成功
if(username.equals(name) &&password.equals(pwd)){
//都一致
System.out.println("恭喜您,登录成功,可以开始玩猜数字游戏了...") ;
StartGuessGame.startGame();
//加入while循环 提示"您还玩吗?y/n"
break ;
}else{
//不成立,继续完成逻辑
//如果3次机会用完,提示"您的电脑被锁住了,请联系管理员";如果三次机会没有用完,提示 "还剩多少次次机会"
if((2-x)==0){
//换一种错误提示
System.out.println("对不起,您电脑被锁住了,请联系管理员!");
}else{
//没有用完
System.out.println("你还剩"+(2-x)+"次机会");
}
}
}
}
}
packagecom.qf.test_02;
importjava.util.Scanner;
/**
* 开始猜数字游戏
*/
publicclassStartGuessGame {
privateStartGuessGame(){}
//对外提供公共 静态方法
publicstaticvoidstartGame(){
//产生随机数
intnum= (int)(Math.random() *100+1);
intcount=0 ;
while(true){
count++ ;
//创建键盘录入对象
Scannersc=newScanner(System.in) ;
//提示并录入数据
System.out.println("请输入要猜的数字:");
intguessNumber=sc.nextInt() ;
if(guessNumber>num){
System.out.println("您要猜的数字"+guessNumber+"大了");
}elseif(guessNumber<num){
System.out.println("您要猜的数字"+guessNumber+"小了");
}else{
System.out.println("恭喜您,第"+count+"猜中了");
break ;
}
}
}
}
3月14号作业
package com.qf.test_02;
public class BwfOuterClass {
private int x = 1;
private int y = 2;
private class BwfInnerClass{//私有的成员内部类
private int x = 3;
public void print(){
//成员内部类的成员是直接访问内部类的成员变量,包括私有
System.out.println("x+y="+(this.x+BwfOuterClass.this.y) );
}
}
public static void main(String[] args) {
//外部类对象.内部类对象.成员方法
new BwfOuterClass().new BwfInnerClass().print();
}
}
package com.qf.test_02;
/**
*
*/
public class Test3 {
public static void main (String[] args){
A.Inner inner = new A().new Inner(); //非静态的成员内部类的格式
inner.show();
}
}
class A{
// int y = 6;
class Inner {
// static int y = 3;
int y = 3 ;
void show() {
System.out.print(y);
}
}
/* public static int num = 10 ;
public int num2 = 20 ;
public void method(){
System.out.println(num) ;
System.out.println(num2);
}*/
}
/*
* 外部类直接访问非静态的成员内部类的成员方法的时候,该成员方法在访问本类的成员变量,只能访问非静态的东西,
* static是随着类的加载而加载,静态的变量比内部类先加载!
* */
package com.qf.test_02;
//看程序,写结果
interface IA{
void m1();
}
class IAImpl1 implements IA{
public void m1(){
System.out.println("impl1");
}
}
class IAImpl2 implements IA{
public void m1(){
System.out.println("impl2");
}
}
class MyClass{
private IA ia;//声明IA接口类型的变量ia
public MyClass(IA ia){ // 形式参数是接口,需要当前接口子实现类对象
this.ia = ia; //this.ia = ia ===>new IAImpl1()
}
public void setIa(IA ia){
this.ia = ia; //this.ia = ia2 ===new IAImpl2() ;
}
public void myMethod(){
ia.m1(); //new IAImpl2()第二个子实现类对象. m1() ;
}
}
public class TestMyClass{
public static void main(String args[]){
IA ia1 = new IAImpl1();
MyClass mc = new MyClass(ia1);
mc.myMethod();
IA ia2 = new IAImpl2();
mc.setIa(ia2); //将第二个子实现类对象传进去
mc.myMethod();
}
}
反转字符串
package com.qf.test_03;
/**
* @author 高圆圆
* @date 2023/3/15 17:41
*/
public class Test3 {
public static void main(String[] args) {
String s = "To be or not to be" ;
String result = reverseMyStr(s);
System.out.println(result);
}
private static String reverseMyStr(String s) {
String[] strArray = s.split(" ") ;
//创建一个字符串缓冲区
StringBuffer sb =new StringBuffer() ;
StringBuffer buffer = null ;
//遍历字符串数组
for(int x = 0 ; x <strArray.length;x++ ){
String ss = strArray[x] ;
//创建一个新的字符串缓冲区区
buffer = new StringBuffer(ss) ; // Tobeornottobe
//反转
buffer.reverse() ;//otebrotonoteb
buffer.append(" ") ;
sb.append(buffer) ; //
}
return sb.toString() ;
}
}
内部类灯光问题
package com.qf.test_04;
/**
* interface Light{
* void shine();
* }
* //定义Lamp 类:
* class Lamp{
* public void on(Light light){
* light.shine();
* }
* }
* //写一个类TestLamp,部分代码如下:
* public class TestLamp{
* public static void main(String args[]){
*
* Lamp lamp = new Lamp();
* //1
* //2
*
* }
* }
* 把TestLamp 类补充完整,要求:
* 1) 在//1 处使用局部内部类技术,调用lamp 的on 方法要求输出"shine in red"
* 2) 在//2 处使用匿名内部类技术,调用 lamp 的 on 方法要求输出"shine in yellow"
*/
interface Light{
void shine();
}
class Lamp{
public void on(Light light){//形式参数是一个接口,需要传给接口子实现类对象
light.shine();
}
}
public class TestLamp {
public static void main(String[] args) {
Lamp lamp = new Lamp();
//1)写一个局部内部类
/*class LightImpl implements Light{
@Override
public void shine() {
System.out.println("shine in red");
}
}
lamp.on(new LightImpl());*/
//2)匿名内部类
lamp.on(new Light() {
@Override
public void shine() {
System.out.println("shine in yellow");
}
});
/*lamp.on(
()-> {
System.out.println("shine in yellow");
}
);*/
}
}
StringBuffer常用类
StringBuffer
package com.qf.stringbuffer_03;
/**
* StringBuffer:字符串缓冲区,线程安全的,支持可变的字符序列!
* 什么叫线程安全----->后面讲的多线程
* 线程安全----> 意味"同步"---->执行效率低!---"银行类的网站!"
* 线程不安全---->意味"不同步"---->执行效率高!----"论坛的网站!"---不安全--->"锁机制"来解决线程安全问题(多线程)
* 面试题:
* StringBuffer和StringBuilder的区别?
* 这两个类都是字符串缓冲区,都支持可变的字符序列,(都有相同的功能)
* 前者:使用在多线程环境里面,能够保证线程安全----意味着同步----->执行效率低
* 后者:是StringBuffer的简易替换,用于在单线程环境中,线程不安全---不同步---执行效率高!
* 单线程使用StringBuilder:效率高(速度快)
*
* 构造方法
* public StringBuffer():无参构造方法,里面空的字符序列,初始容量16个字符(默认容量足够大) -
* public StringBuffer(String str):将字符串构造为StringBuffer类型,容量是大小:当前的里面的字符串长度+16
* 前两个构造方法使用居多!
* public StringBuffer(int capacity):创建一个字符串缓冲区,指定容量大小
* 获取字符串缓冲区的长度 ---int length()
* 获取字符串缓冲区的容量---int capacity()
*/
public class StringBufferDemo {
public static void main(String[] args) {
//创建一个字符串缓冲区对象
StringBuffer sb = new StringBuffer() ;
System.out.println("sb:"+sb) ;
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println("-------------------------");
StringBuffer sb2 = new StringBuffer("hello") ;
System.out.println("sb2:"+sb2) ;
System.out.println(sb2.length()) ;
System.out.println(sb2.capacity());
System.out.println("-----------------------------");
StringBuffer sb3 = new StringBuffer(50) ;
System.out.println(sb3) ;
sb3.append("hello").append('A') ;
System.out.println(sb3.length()) ;
System.out.println(sb3.capacity());
}
}
StringBuffer的添加/删除的功能
package com.qf.stringbuffer_03;
/**
* StringBuffer的添加/删除的功能
* 添加:
* public StringBuffer append(任意java类型) 可以将任意类型的元素添加(在末尾追加)到字符串缓冲区中,返回值是字符串缓冲区本身
*
* public StringBuffer insert(int offset,任意java类型):在指定位置处的序列前面插入新的序列
* 删除:
* public StringBuffer deleteCharAt(int index):在指定位置处删除指定的字符,返回字符串缓冲区本身
* public StringBuffer delete(int start,int end):从指定位置start处开始到end-1处的字符序列删除,
* 返回值字符串缓冲区本身
*
* 开发中使用居多:追加功能以及删除 deletCharAt(int index)使用居多
*/
public class StringBufferDemo2 {
public static void main(String[] args) {
//创建一个字符串缓冲区
StringBuffer sb = new StringBuffer() ;
System.out.println(sb) ;
//public StringBuffer append(任意java类型)
//StringBuffer sb2 = sb.append('A');
//StringBuffer sb3 = sb2.append("helloworld");
//直接追加,可以任何类型数据
//sb.append("hello").append('A').append(true).append(100).append(new Object());
sb.append("hello") ;
sb.append("world") ;
sb.append("java") ;
System.out.println(sb);
//public StringBuffer insert(int offset,任意java类型):在指定位置处的序列前面插入新的序列
sb.insert(5,"高圆圆") ;
System.out.println(sb); //hello高圆圆worldjava
System.out.println("-----------------------------------------");
/**
* public StringBuffer deleteCharAt(int index):在指定位置处删除指定的字符,返回字符串缓冲区本身
* public StringBuffer delete(int start,int end):从指定位置start处开始到end-1处的字符序列删除,
* 返回值字符串缓冲区本身
*/
sb.deleteCharAt(5) ;
System.out.println(sb);
sb.delete(5,10) ;
System.out.println(sb);
}
}
StringBuffer的特有功能:将字符串缓冲区中所有的字符序列反转!
package com.qf.stringbuffer_03;
import java.util.Scanner;
/**
* StringBuffer的特有功能:
* public StringBuffer reverse() :字符串缓冲区反转功能,将字符串缓冲区中所有的字符序列反转!
*
* 需求:
* 键盘录入一个字符串,将字符串反转
*
* 方式1:不让你使用StringBuffer的特有功能,让你使用String
* 1)将录入的字符串---->转换成字符数组
* 2)定义一个String s = "" ;
* 3)将字符数组倒着遍历
* for(int i = 字符数组.length-1;i>0 ;i --){
* s += 字符数组[i] ;
*
* }
* 4)返回结果变量s
*/
public class StringBufferDemo3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入一个字符串:" ) ;
String line = sc.nextLine() ;
//调用一个功能完成
String result = reverse(line);
System.out.println(result) ;
System.out.println("---------------------------------------") ;
String result2 = reverse2(line);
System.out.println(result2);
}
//方式2:使用StringBuffer的反转功能
public static String reverse2(String s){
/*StringBuffer sb = new StringBuffer() ;
sb.append(s) ;
return sb.reverse().toString() ;*/
return new StringBuffer(s).reverse().toString() ;
}
public static String reverse(String s){
//定义一个空字符串
String result = "" ;
//将s字符串-->转换功能 --->字符数组
char[] chs = s.toCharArray();
for(int x = chs.length-1 ; x >= 0 ; x--){
result += chs[x] ;
}
return result ;
}
}
StringBuffer其他功能:替换功能
package com.qf.stringbuffer_03;
/**
*StringBuffer其他功能:
* 替换功能
* public StringBuffer replace(int start,int end,String str)
* 使用指定的字符串str从指定位置开始到end-1处进行替换,返回该字符串缓冲区本身
* public String substring(int start):从指定位置开始截取,默认截取到末尾,返回被截取后的字符串
* public String substring(int start,int end):从指定位置开始截取到指定位置end-1处,返回被截取后的字符串
*
*/
public class StringBufferDemo4 {
public static void main(String[] args) {
//创建一个字符串缓冲区对象
StringBuffer sb = new StringBuffer() ;
sb.append("hello") ;
sb.append("world") ;
sb.append("javaee") ;
System.out.println(sb) ;
//public StringBuffer replace(int start,int end,String str)
sb.replace(5,10,"高圆圆") ;
System.out.println(sb) ;
System.out.println("-------------------------------------");
//String str = sb.substring(5);
//System.out.println(str);
System.out.println(sb.substring(5,8));
}
}
String<---->StringBuffer相互转换 (重点)
package com.qf.stringbuffer_03;
/**
*
* 在开发中,需要将A类型转换成B类型,因为需要使用B类型的功能
* 但是结果可能需要A类型,又需要将B类型转换A类型!
*
* String<---->StringBuffer相互转换 (重点)
*
*
*
*/
public class StringBufferTest {
public static void main(String[] args) {
//String---->StringBuffer
String s = "hello" ;
// StringBuffer sb = s ;
//方式1)可以通过StringBuffer的有参构造方法
//StringBuffer(String str)
//创建一个字符串缓冲
StringBuffer sb = new StringBuffer(s) ;
System.out.println(sb) ;
System.out.println("-------------------------") ;
//方式2:通过StringBuffer的无参构造方法+append(String str)
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;
System.out.println(sb2);
System.out.println("---------------StringBuffer-->String------------------");
//有一个字符串缓冲区--->里面存在字符序列
StringBuffer buffer = new StringBuffer("100") ;
//方式1) -->public String toString()
String str = buffer.toString();
System.out.println(str) ;
System.out.println("----------------------------------------") ;
//方式2:String类的构造方法
//public String(StringBuffer buffer)
String str2 = new String(buffer) ;
System.out.println(str2) ;
}
}
面试题:String和StringBuffer的区别?
package com.qf.stringbuffer_03;
/**
*看程序,写结果
*
* 面试题:
* String和StringBuffer的区别?
* String特点:字符串是一个常量,一旦被创建,其值不能被更改
* String作为形式参数,形参的改变不会影响实际参数;
* 而除过String这个引用类型之外,形式参数的改变直接影响实际参数!
* StringBuffer特点:
* 字符串缓冲区支持可变的字符串,线程安全,执行效率低!
*
*/
public class StringBufferTest2 {
public static void main(String[] args) {
String s = "hello" ;
System.out.println(s) ;
change(s) ;
System.out.println(s);
System.out.println("----------------------------");
StringBuffer sb = new StringBuffer("qianfeng") ;
System.out.println(sb) ;
change(sb);
System.out.println(sb) ;
}
public static void change(StringBuffer buffer){
buffer.append("123") ;//qianfeng123--->返回值StringBuffer
System.out.println(buffer) ;
}
public static void change(String str) {
str += "worldjavaee" ;
System.out.println(str) ;
}
}
键盘录入字符串,判断该字符串是否是对称字符串 (功能改进)
package com.qf.stringbuffer_03;
import java.util.Scanner;
/**
* 键盘录入字符串,判断该字符串是否是对称字符串 (功能改进)
* 举例: "aba" ,"abmba"都是对称字符串
*
* 分析:
* 方式1:
* 1)录入一个字符串
* 2)将字符串转换成字符数组
* 3)使用字符数组第一个元素和数组.length-1的元素进行对比
* 依次对比,如果都一致,就是对称字符串,否则不是对称
* 保证数组长度/2
*
*/
public class StringBufferTest3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入一个字符串:") ;
String line = sc.nextLine() ;
boolean flag = isSame(line);
System.out.println(flag) ;
System.out.println("--------------------------------------------");
boolean flag2 = isSame2(line);
System.out.println(flag2) ;
}
//方式2:
public static boolean isSame2(String s){
//利用StringBuffer的反转
//如果将s--->转换StringBuffer---->反转----->转换成String---->和转换之前String可以equals(),就是对称的,否则不对称
//分步写
/* StringBuffer sb = new StringBuffer() ;
sb.append(s) ;
String str = sb.reverse().toString();
return str.equals(s) ;*/
//一步走
return new StringBuffer(s).reverse().toString().equals(s) ;
}
//定义一个功能
public static boolean isSame(String s){
//假设
boolean flag = true ;
//将字符串转换字符数组
char[] chs = s.toCharArray();
for(int x = 0 ; x < chs.length/2 ; x++){
if(chs[x] !=chs[chs.length-1-x]){//两个字符比较 :比较ASCII码表的值是否相同
flag = false ;
break ;
}
}
return flag ;
}
}
Integer常用类
jdk提供了一个类Integer类,提供了一些功能:十进制转换成对应的进制的方法(静态方法)
package com.qf.integer_04;
/**
*
* 需求:
* 通过java程序,快速得出100的十六进制/八进制/二进制
* 通过java程序获取int类型的取值范围
*
*jdk提供了一个类Integer类,提供了一些功能:十进制转换成对应的进制的方法(静态方法)
*
* 四类八种的基本数据类型都会自动提升 对应的引用类型 jdk5以后新特性:自动拆装箱
*
* 拆箱:
* 这些包装类类型--->降为 基本类型
* 装箱:
* 就是基本类型--->提升 对应的引用类型
*
* 基本类型 引用类型的默认值null
* byte Byte
* short Short
* int Integer(特殊)
* long Long
*
* float Float
* double Double
*
* char Character(特殊)
*
* boolean Boolean
*
* 这些四类八种中的基本数据类型可以String进行相互转换的---->中间桥梁 ---->对应的基本类型的包装类类型!
* String-->Integer--->int
* "100" --->100
*
* String--Long-->long
*
*
*
* Integer和Character涉及相关功能
*
*/
public class IntegerDemo {
public static void main(String[] args) {
//public static String toOctalString(int i) 以字符串形式体现八进制
//public static String toHexString(int i) 以字符串形式体现16进制
//public static String toBinaryString(int i)以字符串形式体现的2进制
System.out.println(Integer.toBinaryString(100));
System.out.println(Integer.toOctalString(100));
System.out.println(Integer.toHexString(100));
System.out.println("-------------------------------------");
//public static final int MAX_VALUE:常量:获取int的最大值
//public static final int MIN_VALUE:常量:获取int的最小值
System.out.println(Integer.MIN_VALUE) ;
System.out.println(Integer.MAX_VALUE) ;
}
}
Integer类表示包含int类型的值
package com.qf.integer_04;
/**
* Integer类表示包含int类型的值
* Integer类的构造方法:
* public Integer(int value):创建一个Integer实例,里面包含的int类型的值
* public Integer(String s) throws NumberFormatException: 将数字字符串转换成Integer的实例
* 可能会出现数字格式化异常(字符串如果不是数字字符串,就会出现这个异常)
*
*/
public class IntegerDemo2 {
public static void main(String[] args) {
//创建一个Integer实例
//public Integer(int value):创建一个Integer实例,里面包含的int类型的值
int a = 100 ;
Integer i = new Integer(a) ;
System.out.println(i) ;
System.out.println("-----------------------------") ;
// public Integer(String s) throws NumberFormatException:
//Integer i2 = new Integer("hello") ;//NumberFormatException:数字格式化异常
Integer i2 = new Integer("50") ;
System.out.println(i2);
}
}
快速拆装箱
package com.qf.integer_04;
/*
拆箱:
* 这些包装类类型--->降为 基本类型
* 装箱:
* 就是基本类型--->提升 对应的引用类型
*
* 基本类型 引用类型的默认值null
* byte Byte
* short Short
* int Integer(特殊)
* long Long
*
* float Float
* double Double
*
* char Character(特殊)
*
* boolean Boolean
*/
public class IntegerDemo3 {
public static void main(String[] args) {
//将100赋值给Integer类型的变量i
Integer i = 100 ; //整数常量赋值Integer类型变量i 装箱
i += 200 ; //先拆箱,在装箱
System.out.println("i:"+i);
}
}
/**
* 反编译的结果:
* Integer i = Integer.valueOf(100); //自动装箱 int--->Integer //public static Integer valueOf(int i)
* i = Integer.valueOf(i.intValue() + 200); // i.intValue()--->public int intValue()--->将Integer-->int
* //先自动拆箱,然后再通过valueOf(300)--->在装箱!
* System.out.println((new StringBuilder()).append("i:").append(i).toString());
* //单线程使用StringBuilder替代StringBuffer
* }
*/
int基本类型和引用String的相互转换 (重点)
package com.qf.integer_04;
/**
* int基本类型和引用String的相互转换 (重点)
*
* String---int: int 变量名 = Integer.parseInt(已知的数字字符串) 推荐
* int---->String: Integer类提供静态方法 String 变量名 = Integer.toString(int类型的值)
*/
public class IntegerDemo4 {
public static void main(String[] args) {
//int---->String
//方式1)比较简单
int i = 100 ;
String s = "" ;
s += i ; //拼接符号 s = s+i
System.out.println(s) ;//"100"
System.out.println("-----------------------------------------") ;
//方式2):int---->Integer----->String
//int-->Integer
//Integer integer = new Integer(i) ; //有参构造方法
Integer integer = Integer.valueOf(i);
//Integer--->String
String str = integer.toString();
System.out.println(str);
System.out.println("----------------------------------------------") ;
//方式3:Integer---->String
//public static String toString(int i)
String str2 = Integer.toString(i);
System.out.println(str2);
System.out.println("---------------------String-->Integer->int----------------------------") ;
//推荐一步执行:
//Integer类提供了静态方法
//public static int parseInt(String s)throws NumberFormatException:要转的字符串必须为数字字符串
//万能方法:String--->long --->Long引用提供静态方法 public static long pasreLong(String str)
//...
String source = "1990" ;
int value = Integer.parseInt(source);
System.out.println(value) ;
System.out.println("------------------------------------------");
//分步执行
//String--->Integer---->int
//Integer(String str)
Integer ii = new Integer(source) ;
//Integer--->int public int intValue() :
int value2 = ii.intValue();
System.out.println(value2) ;
}
}
Integer是int类型的包装类类型,它里面的特点
package com.qf.integer_04;
/**
* 看程序写结果
*
* 考点:
* Integer是int类型的包装类类型,它里面的特点
*
* Integer:
* 将int类型赋值给Integer变量 这种格式,执行底层方式valueOf(int i)
*
*
* public static Integer valueOf(int i) {
* 如果i的值在-128~127之间,直接从内部类--->IntegerCache缓存去中取数据
* if (i >= IntegerCache.low && i <= IntegerCache.high)
* return IntegerCache.cache[i + (-IntegerCache.low)]; // cache属性:Integer cache[] 长度 =i+128
* return new Integer(i); //如果上if不成立,重新开辟新的空间创建Integer实例
* }
*
*/
public class IntegerTest {
public static void main(String[] args) {
Integer i1 = 127 ;
Integer i2 = 127 ;
System.out.println(i1==i2) ; //true
System.out.println(i1.equals(i2)) ; //true比较内容
Integer i3 = 127 ;
Integer i4 = new Integer(127) ;
System.out.println(i3==i4) ; //false
System.out.println(i3.equals(i4)) ;//true
Integer i5 = 128 ; //new Integer(128) ;
Integer i6 = 128 ;//new Integer(128);
System.out.println(i5==i6) ; //false
System.out.println(i5.equals(i6)) ;//true
Integer i7 = new Integer(128) ;
Integer i8 = new Integer(128) ;
System.out.println(i7==i8) ; //false
System.out.println(i7.equals(i8)) ;//true
}
}
CharacterDemo常用类
char类型的包装类类型:Character
package com.qf.character_05;
/**
* char类型的包装类类型:Character
* 构造方法:
* public Character(char value):包含char类型的值
* 成员方法:
* 判断功能:
* public static boolean isDigit(char ch):判断当前这个字符是否为数字
* public static boolean isLowerCase(char ch):判断当前这个字符是否小写
* public static boolean isUpperCase(char ch):判断当前这个字符是否大写
*/
public class CharacterDemo {
public static void main(String[] args) {
//创建一个Character类的实例
// Character ch = new Character('a') ;
Character ch = new Character((char)97) ;
System.out.println(ch) ;
System.out.println("----------------------------------------------");
System.out.println(Character.isDigit('A')) ;
System.out.println(Character.isDigit('a')) ;
System.out.println(Character.isDigit('0')) ;
System.out.println(Character.isLowerCase('0')) ;
System.out.println(Character.isLowerCase('a')) ;
System.out.println(Character.isLowerCase('A')) ;
}
}
键盘录入一个字符串,统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。
package com.qf.character_05;
import java.util.Scanner;
/**
*需求:键盘录入一个字符串,统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符)
* 举例:
* "Hello123World"
*
* 提示:统计字符定义三个统计变量,分别代表大写字母字符,小写字母字符,数字字符
* 'A'-'Z' 大写
* 'a'-'z' 小写
* '0'-'9' 数字
*/
public class CharacterTest {
public static void main(String[] args) {
//定义一个三个统计变量
int upperCount = 0 ;
int lowerCount = 0 ;
int digitCount = 0 ;
//键盘录入一个字符串
Scanner sc= new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个字符串:") ;
String line = sc.nextLine() ;
//选择核心代码--->快速抽取一个方法:ctrl+alt+M--->修改方法名即可!
getCharCount(upperCount, lowerCount, digitCount, line);
}
private static void getCharCount(int upperCount, int lowerCount, int digitCount, String line) {
//将字符串转换成字符数组
char[] chs = line.toCharArray();
//遍历字符数组
/* for(int x = 0 ; x < chs.length ; x++){
//获取每一个字符
char ch = chs[x] ;
//判断
if(ch >= 'A' && ch <= 'Z'){
//大写字母字符
upperCount++;
}else if(ch >='a' && ch <= 'z'){
//小字母字符
lowerCount++ ;
}else{
//数字字符
digitCount++ ;
}
}*/
//使用另一种方式
for(int x = 0 ; x < chs.length ; x++){
char ch = chs[x] ;//获取字符
//使用Character类提供的特有功能
if(Character.isUpperCase(ch)){
upperCount ++ ;
}else if(Character.isLowerCase(ch)){
lowerCount ++ ;
}else if (Character.isDigit(ch)){
digitCount++ ;
}else{
System.out.println("没有其他字符类型");
}
}
System.out.println("大写字母字符共有:"+ upperCount +"个,小写字母有:"+ lowerCount +
"个,数字字符有:"+ digitCount +"个");
}
}
day20
晨写
#晨写
##1.String和int的相互转换
```java
//int--->String
//1)使用字符串拼接符号 ""+任何类型数据= "新的字符串"
//2)int--->Integer---->String
inti=100 ;
Integerinteger=newInteger(i) ;
Stringstr=integer.toString() ;
//3)Integer的静态方法 public static String toString(int i)
Stringstr2=Integer.toString(i) ;
//String--->int(使用的比较频繁)
//1)String---->Integer---->int
Stringsource="10" ;
Integerinteger2=newInteger(source) ;
intvalue=integer2.intValue() ;
//2)Integer提供的静态方法 public static int parseInt(String s)
intvalue2=Integer.parseInt(source);
```
##2.StringBuffer和String的相互转换
```java
//String--->StringBuffer
//1)通过StringBuffer无参构造方法 + 结合 append(String str)
Strings="helloworld" ;
StringBufferbuffer=newStringBuffer() ;
buffer.append(s) ;
//2)直接通过StringBuffer的有参构造方法
StringBufferbuffer2=newStringBuffer(s) ;
//StringBuffer---->String
//1)通过StringBuffer的toString()
StringBuffersb =newStringBuffer("JavaEE") ;
Stringstr=sb.toString() ;
//2)通过String的构造方法 String(StringBuffer/StringBuilder buffer)
Stringstr2=newString(sb) ;
```
##3.StringBuffer和StringBuilder的区别?
```markdown
StringBuffer和StringBuilder的共同点:
他们都支持可变的字符序列,都代表字符串缓冲区(存储的都是字符序列)(都是容器),底层都是会存在char[];
他们作为方法形式参数,形式参数的改变都会影响实际参数!
他们具有相互兼容的API
不同点:
StringBuffer是线程安全的类---->
他们几乎所有的成员方法都有一个关键字"synchronized"-->同步锁(悲观锁),能够解决线程安全问题,所以在盗用
StringBuffer的方法时候,执行效率低!
StringBuilder是线程不安全的类,单线程程序(不考虑安全,只考虑执行效率)使用StringBuilder去替代StringBuffer,提高执行效率!(相对StringBuffer,执行效率高)
```
##4.Integeri=int值; 这个方法底层怎么执行的?
```java
publicstaticIntegervalueOf(inti) {}
//在Integer类中---IntegerCache:Integer的内部缓存区,low=-128,high=127
//IntegerCache--->cache[] 数组,给这个Integer类型数组完成动态初始化
/*
如果i的值在-128~127之间,直接内部缓存区中取数据,如果一旦超过这个范围,就会return new Integer(i) ;
*/
```
##5.什么是自动拆装箱
```java
//jdk5以后新特性 :自动拆装箱 / 静态导入/可变参数/泛型<>/枚举..
//自动拆装箱: 基本数据类型会自动提升为对应的引用类型---装箱
//相关的引用类型---自动降为 对应基本数据类型--->拆箱
Integeri=200; //装箱---Integer.valueOf(200)
i+=100 ; //i = i + 100 ; //将Integer的值200--->降为int类型--intValue() 和100求和 (拆箱)
//Integer.valueOf(求和结果);在装箱
```
##6.String和StringBuffer的区别?
```markdown
区别:
String:支持不可变的字符,字符串是常量,一旦被创建,其值不能被更改
作为方法的形式参数,形式参数的改变不会影响实际参数(和基本数据类型作为形式参数一致!)
StringBuffer:支持可变的字符序列,可以不断的给里面追加任何类型的数据,包括StringBuffer类型
作为形式参数,形式参数的改变会直接实际参数
```
##Arrays的toString的原码--->将数组转换成Stirng形式
```java
publicstaticStringtoString(int[] a) { //实际参数 --->传入数组对象
if (a==null) //如果是是null
return"null"; "null"
intiMax=a.length-1; //最大索引值
if (iMax==-1) //如果最大索引值是-1
return"[]"; "[]"
StringBuilderb=newStringBuilder(); //单线程中使用StringBuilder
b.append('['); //追加"["
for (inti=0; ; i++) { //遍历a数组
b.append(a[i]); //直接将所有数组的元素追加到字符串缓冲区中
if (i==iMax) //如果角标i取到最大索引值
returnb.append(']').toString(); //结束: 追加"]"--->转换成String
b.append(", "); //没有最大索引值,追加", "
}
}
```
----
----
#今日内容
##1.其他类System/Random/Calendar日历/BigDecimal/Math
##2.重点类:java.util.Date类
```
String日期文本---->java.util.Date类----->将String日期文本解析操作---->java.util.Date
java.util.Date类----->String日期文本 --------------->格式化操作
```
##3.引入集合框架--->存储/取出 (如何遍历Collection/List/Set...)
```
Collection<E>集合 (接口) ------- ----> Map
List接口 Set接口
ArrayList类 HashSet类 ----->关联Map<K,V>---HashMap<K,V>jdk8:数组+链表+红黑树
Vector类 TreeSet类 ----->关联Map<K,V>---TreeMap<K,V>红黑树(自平衡的二叉树)
二叉树:满二叉树/完全二叉树/非完全二叉树
TreeSet存储元素,取(定义排序规则)
LinkedList类
```
System常用类
packagecom.qf.system_01;
importcom.sun.xml.internal.ws.api.message.saaj.SaajStaxWriter;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.PrintStream;
importjava.util.Scanner;
/**
* java.lang.System:不能实例化:提供了静态字段(静态变量)
* public static final PrintStream out :标准 打印输出流
* public static final PrintStream err 标准错误输出流
* public static final InputStream in 标准输入流
*/
publicclassSystemDemo {
publicstaticvoidmain(String[] args) throwsIOException {
// public static final PrintStream out--->类型PrintStream:字节打印流 (写数据)
System.out.println("helloworld");
System.out.println("-----------------------------------");
PrintStreamps=System.out ;
//PrintStream提供各种打印的方法print(不换行任何类型数据)/prinln("换行打印任何类型数据")
ps.print(100) ;
ps.print(true);
ps.write("hello".getBytes());
ps.println();
System.out.println("-----------------------------------");
// public static final PrintStream err 标准错误输出流
PrintStreamps2=System.err ;
ps2.println("这是一个错误输出流打印数据,提示错误信息");
System.out.println("---------------------------------------");
//public static final InputStream in 标准输入流 :读数据
InputStreamis=System.in ;
//创建键盘录入对象
//public Scanner(InputStream source)
Scannersc=newScanner(is) ;
System.out.println("请输入一个数据:");
inta=sc.nextInt() ;
System.out.println(a);
}
}
packagecom.qf.system_01;
importjava.util.Arrays;
/**
* System类常用的成员方法:
*
* public static long currentTimeMillis() 计算当前系统时间毫秒值 (很少单独用)
* 用来计算当前某个程序的时间复杂度(运行效率)
*
* public static void gc() 收到开启垃圾回收器 ---会调用finalize(),回收没有更多引用的对象
* public static void exit(int status): 参数为0:终止jvm
* public static void arraycopy(
* Object src, //原对象
* int srcPos, //原对象中的某个位置
* Object dest, //目标对象
* int destPos, //目标对象的某个位置
* int length) //指定的长度
*/
publicclassSystemDemo2 {
publicstaticvoidmain(String[] args) {
//public static long currentTimeMillis() 计算当前系统时间毫秒值
//long time = System.currentTimeMillis() ;
//System.out.println(time);
/* long start = System.currentTimeMillis() ;
System.out.println(start);*/
// System.exit(0) ;//正常终止jvm
/* for(int x = 0 ; x < 100000; x++){
System.out.println("helloworld:"+x);
}
long end = System.currentTimeMillis() ;*/
//System.out.println("共耗时:"+(end-start)+"毫秒");
System.out.println("--------------------------------------------------------");
/**
* public static void arraycopy(
* Object src, //原对象
* int srcPos, //原对象中的某个位置
* Object dest, //目标对象
* int destPos, //目标对象的某个位置
* int length) //指定的长度
*/
int[] arr= {11,22,33,44,55} ;
int[] arr2= {1,2,3,4,5,6,7,8} ;
//Arrays的toString(数组对象)---输出字符串
System.out.println("复制前:") ;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr2));
System.arraycopy(arr,1,arr2,2,3);
System.out.println("----------------------------------") ;
System.out.println("复制之后:") ;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr2));
}
}
Random
packagecom.qf.random_02;
importjava.util.Random;
/**
* java.util.Random:伪随机数生成器 可以产生随机数 比Math.random()麻烦
* 两个构造方法:
* public Random() :无参构造方法(推荐)
* public Random(long seed):有参构造,创建一个指定long类型的变量的随机数生成器
* 两个成员方法:
* public int nextInt(): 产生伪随机数在,取值是int类型 的范围内
* public int nextInt(int n):产生0-n之间的随机数(推荐)
*/
publicclassRandomDemo {
publicstaticvoidmain(String[] args) {
//public Random(long seed):有参构造,创建一个指定long类型的变量的随机数生成器
// Random r = new Random(1000) ;
Randomr=newRandom() ;
//产生10个随机数
for(intx=0 ; x<10 ; x++){
// public int nextInt(): 产生伪随机数在,取值是int类型 的范围内
//int number = r.nextInt();
//System.out.println(number);
intnumber=r.nextInt(50);
System.out.println(number);
}
}
}
packagecom.qf.random_02;
importjava.util.Random;
/**
* java.util.Random:伪随机数生成器 可以产生随机数 比Math.random()麻烦
* 两个构造方法:
* public Random() :无参构造方法(推荐)
* public Random(long seed):有参构造,创建一个指定long类型的变量的随机数生成器
* 两个成员方法:
* public int nextInt(): 产生伪随机数在,取值是int类型 的范围内
* public int nextInt(int n):产生0-n之间的随机数(推荐)
*/
publicclassRandomDemo {
publicstaticvoidmain(String[] args) {
//public Random(long seed):有参构造,创建一个指定long类型的变量的随机数生成器
// Random r = new Random(1000) ;
Randomr=newRandom() ;
//产生10个随机数
for(intx=0 ; x<10 ; x++){
// public int nextInt(): 产生伪随机数在,取值是int类型 的范围内
//int number = r.nextInt();
//System.out.println(number);
intnumber=r.nextInt(50);
System.out.println(number);
}
}
}
Calendar常用类
packagecom.qf.calendar_03;
importjava.util.Calendar;
/**
* java.util.Calendar:日历类(抽象类)
* 提供了获取年,年中的月,月中的日期,小时,小时分钟数,分钟中的秒数都可以获取到
*
* 如果有一个类是抽象类,可以直接new子类,或者是它提供了一些静态方法---->
* 完成了一些事情,创建子类对象,返回值是当前抽象类的本身
*
* 成员方法:
* public static Calendar getInstance() 创建日历对象
* public int get(int field):通过日历对象获取日历中的字段值
*
* 参数:Calendar中提供的一些静态字段
* public static final int YEAR:年份
* public static final int DAY_OF_MONTH/public static final int DATE:月中的日期
* public static final int MONTH:月份
*
* public abstract void add(int field,int amount):给指定的日历字段值添加或者减去时间偏移量
*
*/
publicclassCalendarDemo {
publicstaticvoidmain(String[] args) {
//创建一个日历对象
//Calendar c = new Calendar() ; //不能实例化:抽象类
//如何实例化-->public static Calendar getInstance()
Calendarc=Calendar.getInstance(); //getInstance()--->创建Calendar类的子类对象
System.out.println(c);
System.out.println("-----------------------------------------");
// public static final int YEAR:年份
// public static final int DAY_OF_MONTH/public static final int DATE:月中的日期
// public static final int MONTH:月份
//public int get(int field):通过日历对象获取日历中的字段值
intyear=c.get(Calendar.YEAR);
intmonth=c.get(Calendar.MONTH) ;//默认计算0-11
intdate=c.get(Calendar.DAY_OF_MONTH) ;
System.out.println(year+"-"+(month+1)+"-"+date);
System.out.println("-----------------------------------------") ;
//public abstract void add(int field,int amount):给指定的日历字段值添加或者减去时间偏移量
//3年后的今天
/* c.add(Calendar.YEAR,3) ;
year = c.get(Calendar.YEAR) ;
month = c.get(Calendar.MONTH) ;//默认计算0-11
date = c.get(Calendar.DAY_OF_MONTH) ;
System.out.println(year+"-"+(month+1)+"-"+date);*/
System.out.println("-------------------------------------------") ;
//5年前的10天前
c.add(Calendar.YEAR,-5);
c.add(Calendar.DAY_OF_MONTH,-10);
year=c.get(Calendar.YEAR) ;
month=c.get(Calendar.MONTH) ;//默认计算0-11
date=c.get(Calendar.DAY_OF_MONTH) ;
System.out.println(year+"-"+(month+1)+"-"+date) ;
}
}
BigDeimal常用类
packagecom.qf.bigdecimal_04;
importjava.math.BigDecimal;
/**
*BigDecimal这个类是对小数可以进行精确计算的!
* 构造方法:
*
* public BigDecimal(String val):将String类型数据构造成BigDecimal
* 将double数据---使用"小数字符串"
*
* 成员方法:
* public BigDecimal add(BigDecimal augend):求和
* public BigDecimal subtract(BigDecimal subtrahend):相减
* public BigDecimal divide(BigDecimal divisor):小数除法
* public BigDecimal divide(BigDecimal divisor,int roundingMode):除法,第二个参数舍入模式
*
* BigDecimal提供的模式 public static final int ROUND_HALF_UP:四舍五入
* ...
* public BigDecimal divide(BigDecimal divisor,
* int scale,//保留几位小数
* int roundingMode) //舍入模式
* public BigDecimal multiply(BigDecimal multiplicand):乘法
*/
publicclassBigDecimalDemo {
publicstaticvoidmain(String[] args) {
//System.out.println(1.01/0.35) ;
BigDecimalbd1=newBigDecimal("0.35") ;
BigDecimalbd2=newBigDecimal("0.35") ;
//public BigDecimal add(BigDecimal augend):求和
System.out.println(bd1.add(bd2)) ;
System.out.println("-------------------------------------------");
// public BigDecimal subtract(BigDecimal subtrahend):相减
BigDecimalbd3=newBigDecimal("1.01") ;
BigDecimalbd4=newBigDecimal("0.036") ;
System.out.println(bd3.subtract(bd4));
System.out.println("-------------------------------------------");
System.out.println(bd3.divide(bd4,BigDecimal.ROUND_HALF_UP));
System.out.println(bd3.divide(bd4,1,BigDecimal.ROUND_HALF_UP));
System.out.println("---------------------------------------------");
BigDecimalbd5=newBigDecimal("0.35") ;
BigDecimalbd6=newBigDecimal("2.01") ;
System.out.println(bd5.multiply(bd6));
}
}
date常用类
packagecom.qf.date_05;
importjava.util.Date;
/**
* java.util.Date:表单特定的日期时间,还允许格式化和解析日期字符串
* 构造方法:
* public Date():创建当前日期对象:获取当前系统日期时间
* public Date(long date):里面传入long类型的时间毫秒值,获取的表示从标准基准时间(称为“时代”)即1970年1月1日00:00:00 GMT起的指定毫秒数
*成员方法:
* public long getTime():将Date对象转换成long类型时间毫秒值
* public void setTime(long time):设置日期时间,参数时间毫秒值
*
*
*
*
*/
publicclassDateDemo {
publicstaticvoidmain(String[] args) {
//创建Date日期对象
Datedate=newDate() ;
System.out.println(date) ;
//Thu Mar 16 14:07:46 CST 2023
longtime=date.getTime();
System.out.println(time);
//long time = 1000 ;
//创建日期对象public Date(long date)
//Date date = new Date(time) ;
//System.out.println(date) ;
}
}
java.util.Date重点如何和String日期文本相互转换!
packagecom.qf.date_05;
importjava.text.ParseException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
/**
* java.util.Date重点如何和String日期文本相互转换!
*
* 他们之间要进行转换需要使用类DateFormat
* DateFormat是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间
* 它具体的子类:SimpleDateFormat是一个具体的类,允许格式化(日期文本),解析(文本日期)
*
*构造方法:
* public SimpleDateFormat(String pattern):参数是日期模式 "yyyy-MM-dd"
* pattern的组成:
* y:表示年份中某个值----->yyyy 表示年 "1996/2023/..."
* M:表示年中的月份------>MM 表示月:七月-->"07" 十月 -->"10"
* d:表示月中的日期值----->dd 表示 "01","11","31"..
* 成员方法
* 将Date---->String:格式化 public final String format(Date date)
* 将String日期---->Date:解析
*
* public Date parse(String source)throws ParseException
*
*
*
* 定义工具类DateUtils 日期工具类---构造方法私有外,提供静态功能
* 将下面Date---->String格式化---定义功能完成
* 将String---->Date解析---定义功能完成
*/
publicclassDateDemo2 {
publicstaticvoidmain(String[] args) throwsParseException {
//当前系统日期对象
Datedate=newDate() ;
System.out.println(date) ;
//Date---->格式化---->String日期文本
//1)public SimpleDateFormat(String pattern):参数是日期模式
SimpleDateFormatsdf=newSimpleDateFormat("yyyy年MM月dd日 HH:mm:ss") ;
//2)格式化:public final String format(Date date)
StringdataStr=sdf.format(date);
System.out.println(dataStr) ;
System.out.println("-------------------------------------------------------") ;
//String日期文本---->java.util.Date
Stringsource="2008-5-12" ;
//创建SimpleDataFormat
// SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日") ;
SimpleDateFormatsdf2=newSimpleDateFormat("yyyy-MM-dd") ;
//解析public Date parse(String source)throws ParseException
//当SimpletDateFormat和给定日期文本格式不一致,就解析出错
Datedate2=sdf2.parse(source);
System.out.println(date2);
}
}
日期工具类(重点)
package com.qf.date_05;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 定义工具类DateUtils 日期工具类---构造方法私有外,提供静态功能
* 将下面Date---->String格式化---定义功能完成
* 将String---->Date解析---定义功能完成
*/
public class DateUtils {
//构造方法私有化
private DateUtils(){}
//Date---->String格式化---定义功能完成
public static String date2String(Date date,String pattern){
//分步走
//创建SimpleDateFormat
/*SimpleDateFormat sdf = new SimpleDateFormat(pattern) ;
String str = sdf.format(date);
return str;*/
return new SimpleDateFormat(pattern).format(date) ;
}
//String日期文本---解析--->java.util.Date
public static Date string2Date(String dateStr,String pattern) throws ParseException {
return new SimpleDateFormat(pattern).parse(dateStr) ;
}
//测试
public static void main(String[] args) throws ParseException {
String str = DateUtils.date2String(new Date(), "yyyy-MM-dd");
System.out.println(str);
System.out.println("------------------------------") ;
String dateStr = "2026年10月01日" ;
Date date = DateUtils.string2Date(dateStr, "yyyy年MM月dd日");
System.out.println(date) ;
//java.sql.Date----继承---->java.util.Date
System.out.println("-----------------------------------");
//最终将上面日期格式存储数据库中(mysql/oracle....关系型数据库),将java.util.Date--->java.sql.Date
long time = date.getTime();
//创建java.sql.Date对象
java.sql.Date date2 = new java.sql.Date(time) ;
System.out.println(date2) ;//2026-10-01 (java.sql.Date)
}
}
计算来到世界多少天
package com.qf.date_05;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* 键盘录入出生年月日,计算来到这个世界多少天了?
*
* 分析:
* 1)键盘录入String dateStr = "1990-02-27"
* 2)将dateStr日期字符串---->java.util.Date
* 3)获取当前那个Date日期时间 毫秒值 long getTime()
* 4)System提供了一个方法获取当前系统时间毫秒值
* 5)时间差值---然后换算成天
*/
public class DateTest {
public static void main(String[] args) throws ParseException {
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入您的出生年月日:" ) ;
String dateStr = sc.nextLine() ;//yyyy年MM月dd日/yyyy-MM-dd
//将dateStr---->java.util.Date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
Date date = sdf.parse(dateStr);
//获取当前date所在时间毫秒值
long oldTime = date.getTime();
//获取当前系统时间毫秒值
long nowTime = System.currentTimeMillis() ;
long time = nowTime - oldTime ;
System.out.println("您来到这个时间有:"+(time/1000/60/60/24)+"天");
}
}
Collection集合
package com.qf.collection_01;
import java.util.ArrayList;
import java.util.Collection;
/**
* Collection:单例集合顶层次的根接口,不能new,没有直接子实现类,是通过它子接口的子实现类来实例化!
* 泛型: 集合里面创建的时候,如果不带泛型可能程序安全问题;带了<>,模拟创建数组的时候,明确了数据类型!
* <E>:element
* <T>:Type
* <K>:Key键
* <V>:Value值
*
* 基本功能:
* 添加元素:
* boolean add(E e):添加元素
* 删除:
* boolean remove(Object o):删除指定的元素
* void clear():暴力删除:清空集合
* 判断:
* boolean contains(Object o):是否包含指定的元素
* boolean isEmpty():判断集合是否为空
*
*/
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合
//Collection c = new ArrayList() ; //先不带泛型<>
Collection<String> c = new ArrayList<>() ;
//=后面的集合的<> jdk7以后新特性;泛型推断 (加入泛型:保证数据的安全性),创建集合就明确了数据类型
System.out.println(c) ;
//boolean add(E e):添加元素
//add方法--->原码---添加元素永远返回true
//boolean flag = c.add("hello");
//System.out.println(flag);
/*boolean flag2 = c.add("world");
boolean flag4= c.add("world");
System.out.println(flag4);
System.out.println(flag2) ;
boolean flag3 = c.add(100);
System.out.println(flag3);*/
c.add("hello") ;
c.add("world") ;
c.add("javaee") ;
c.add("高圆圆") ;
/* c.add('A') ;
c.add(100) ;
c.add(true) ;
c.add(new Object());*/
System.out.println(c);
System.out.println("-----------------------------------------") ;
//boolean remove(Object o):删除指定的元素
System.out.println(c.remove("赵又廷"));
System.out.println(c.remove("高圆圆"));
System.out.println(c) ;
//c.clear();
//System.out.println(c) ;
System.out.println("--------------------------------------------");
//boolean contains(Object o):是否包含指定的元素
// boolean isEmpty():判断集合是否为空
System.out.println(c.contains("hello")) ;
System.out.println(c.contains("android")) ;
System.out.println(c.isEmpty());
}
}
package com.qf.collection_01;
import java.util.ArrayList;
import java.util.Collection;
/**
* Collection集合高级功能:
* Object[] toArray():集合的传统方式遍历 将集合转换成对象数组(以后不会用的)
* Iterator<E> iterator():Collection专有迭代器(遍历集合) (过渡)
*
* 开发中---集合遍历---->都用jdk5以后新特性:增强for循环 代替上面迭代器
* 使用Collection集合存储5个学生,学生有姓名,年龄,
* 需要在测试类中打印这个5个学生的信息
*/
public class CollectionTest {
public static void main(String[] args) {
//创建一个集合Collection
Collection<Student> c = new ArrayList<>() ;
//创建5个学生
Student s1 = new Student("文章",35) ;
Student s2 = new Student("王宝强",37) ;
Student s3 = new Student("高圆圆",44) ;
Student s4 = new Student("赵又廷",46) ;
Student s5 = new Student("马伊琍",40) ;
Student s6 = new Student("马伊琍",40) ;
//添加功能
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
c.add(s6) ;
//Object[] toArray()
Object[] objects = c.toArray(); //objects--->存储5个学生
for(int x = 0 ;x < objects.length ; x++){
//System.out.println(objects[x]);// objects[x] 类型Object--->每一个学生对象 new Student()
//向下转型
Student student = (Student) objects[x];
System.out.println("学生的姓名是:"+student.getName()+",年龄是:"+student.getAge());
}
/*
jdk5的增强for:针对集合去使用的
for(Student s:c){
System.out.println(s.getName()+"---"+s.getAge());
}*/
}
}
package com.qf.collection_01;
/**
* 学生类
*/
public class Student {
private String name ; //姓名
private int age ; //年龄
public Student() {
}
public Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Iterator迭代器
package com.qf.collection_01;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
*Iterator<E> iterator():Collection专有迭代器(遍历集合) (过渡)
*
* Iterator迭代器接口:
* boolean hasNext(): 判断迭代器里面是否下一个可以遍历的元素
* E next():获取迭代器的下一个元素 (和迭代器中的类型一致)
*
* 开发中---集合遍历---->都用jdk5以后新特性:增强for循环 代替上面迭代器
*
* 需求:
* 使用Collection<Student>存储5个学生对象,使用Iterator<E> iterator()进行遍历!
*
*/
public class CollectionDemo2 {
public static void main(String[] args) {
//使用Collection存储String字符串并进行遍历---使用Collection迭代器
Collection<String> c = new ArrayList<>() ;
//添加String
c.add("android") ;
c.add("JavaEE") ;
c.add("mysql") ;
c.add("hadoop") ;
//c.add(100) ;
//获取Collection的迭代器
//Iterator<E> iterator()
Iterator<String> it = c.iterator();
//E next() //E---类型需要和泛型的类型一致的
/*//第一次取
Object object = it.next();
String s = (String) object;
System.out.println(s);
//第二次取
Object object2 = it.next();
System.out.println((String)object2);
//第三次取
Object object3 = it.next();
System.out.println((String)object3);*/
//第一次取
/* if(it.hasNext()){
String next = it.next();
System.out.println(next);
}
//第二次取
if(it.hasNext()){
System.out.println(it.next());
}
//第三次取
if(it.hasNext()){
System.out.println(it.next());
}
if(it.hasNext()){
//第四次取
System.out.println(it.next());
}
if(it.hasNext()){
//第五次取
System.out.println(it.next());
}*/
//while循环
while(it.hasNext()){
String s = it.next();
System.out.println(s+"---"+s.length());
}
//第五次取
//System.out.println(it.next());//NoSuchElementException:没有元素了
}
}
day21
晨写
#晨写
##1.将Collection集合进行遍历的方式
```java
//暂时两种方式
//将Collection转换成对象数组
Object[] toArray() //传统方式遍历 (不推荐)
Collection<Student>c=newArrayList<>() ;
Students1=newStudent("张三丰",55) ;
Students2=newStudent("高圆圆",44) ;
c.add(s1) ;
c.add(s2) ;
Object[] objects= c.toArray() ;
//遍历对象数组
for(intx=0 ; x<objects.length; x++){
// objects[x] 栈内存的数据类型 Object ---->堆内存都是学生对象 (父类引用指向子类对象)
//直接输出objects[x] 执行学生对象toString方法(toString(),方便自己测试用的)
//想通过Student的getXXX()获取信息表达式
//向下转型
Students= (Student)objects[x] ;
System.out.println(s.getName()+"---"+s.getAge()) ;
}
//Collection集合的迭代器(专有遍历方式)
Iteratoriterator()
```
##2.集合和数组的区别?
```markdown
1)长度的区别
数组:长度是固定的 (无论静态初始化还是动态初始化,都是固定长度)
集合:长度是可变的,在集合中不断添加元素
2)存储数据类型的区别
数组:可以存储基本数据类型,也可以存储引用数据类型!
集合:可以存储任意Java引用类型(没有给定泛型的情况下)
3)存储元素的区别:
数组:无论存储基本数据还是引用类型,元素类型必须一致
举例:存储水杯中的水
集合:没有给定泛型情况下,可以存储不同的引用类型的元素
举例:
水+果汁+其他...
```
##3.Date和String日期文本的相互转换(Java原生格式)
```java
//String日期文本---->转换---->java.util.Date日期对象
Stringsource="2023-03-17" ;
//1)创建中间桥梁(解析器)SimpleDateFormat
SimpleDateFormatsdf=newSimpleDateForamt("yyyy-Mm-dd") ;
//2)解析
Datedate=sdf.parse(source) ; //这个方法本身throws ParseException (当前模式的格式和String日期文本格式不一致,就会出现这个异常!)
//java.util.Date日期对象----->转换------>String日期文本
Datedate2=newDate() ;
//1)创建解析器对象SimpleDateFormat
SimpleDateFormatsdf2=newSimpleDateFormat("yyyy-MM-dd") ;
//2)格式化
StringdateStr=sdf2.format(date2) ;
```
##4.Collection的Iterator的使用方式
```java
//Iterator iterator()
Collection<Student>c=newArrayList<>() ;
Students1=newStudent("张三丰",55) ;
Students2=newStudent("高圆圆",44) ;
c.add(s1) ;
c.add(s2) ;
//将集合中元素交给迭代器
Iterator<Student>it=c.iterator() ;
while(it.hasNext()){
//判断是否有下一个可以迭代的元素
//存在,进来
//获取下一个元素
Students=it.next() ;
System.out.println(s.getName()+"----"+s.getAge()) ;
}
```
##5.获取一个类的字节码文件对象的方式?
```markdown
三种
1)Object类的getClass()方法--->需要使用对象名来访问的 Class(字节码文件对象/正在运行的类对象)
2)任意Java类型的class属性---类名.class---->Class
3)反射---Class.forName("当前类或者接口的全限定名称") ;--->Class
```
------
-----
---
#今日内容
##0.Collection迭代器的原理
```
Collection<xx>c=newArrayList<>() ;
--->ArrayList里面的内部类间接实现Iterator (代码体现结构)
```
##1.List集合去重思想
##2.List三个子实现类的特点以及特有功能
```
ArrayList,Vector(线程安全的类),LinkedList
```
##3.Set集合里面两个子实现类特点
```
HashSet--->底层依赖HashMap---存储元素,取元素---能够保证元素唯一
TreeSet--->底层依赖TreeMap---存储元素,取元素---能够保证元素唯一,而且排序(Integer/String,自然排序)
TreeSet<自定义类型>存储了一些Student
定义排序主要条件:(只给主要条件,自己分析次要条件)
学生的年龄从小到大
```
##4.使用ArrayList模拟登录/注册
```
注册User---给ArrayList添加元素
登录---获取ArrayList集合,遍历元素
注意:
注册和登录功能的集合必须是同一个!
```
使用迭代器去遍历学生信息
packagecom.qf.iterator_01;
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
/**
*使用Collection集合存储5个学生,使用它的迭代器去遍历学生信息
*/
publicclassCollectionDemo {
publicstaticvoidmain(String[] args) {
//创建一个集合
Collection<Student>c=newArrayList<>() ;
//创建学生对象
Students1=newStudent("曹操",45) ;
Students2=newStudent("周瑜",20) ;
Students3=newStudent("刘备",35) ;
Students4=newStudent("关羽",32) ;
Students5=newStudent("张飞",30) ;
//添加
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
//获取Collection集合的迭代器
Iterator<Student>it=c.iterator();
while(it.hasNext()){
//获取下一个元素
Studentstudent=it.next();//调用一次
System.out.println(student.getName()+"---"+student.getAge());
// System.out.println((it.next()).getName()+"---"+(it.next()).getAge()); //错误写法
}
}
}
packagecom.qf.iterator_01;
/**
* 学生类
*/
publicclassStudent {
privateStringname ;
privateint age ;
publicStudent() {
}
publicStudent(Stringname, intage) {
this.name=name;
this.age=age;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name=name;
}
publicintgetAge() {
returnage;
}
publicvoidsetAge(intage) {
this.age=age;
}
@Override
publicStringtoString() {
return"Student{"+
"name='"+name+'\''+
", age="+age+
'}';
}
@Override
publicbooleanequals(Objecto) {
if (this==o) returntrue;
if (o==null||getClass() !=o.getClass()) returnfalse;
Studentstudent= (Student) o;
if (age!=student.age) returnfalse;
returnname.equals(student.name);
}
@Override
publicinthashCode() {
intresult=name.hashCode();
result=31*result+age;
returnresult;
}
}
有一个Collection集合,存储一些不重复的String元素,如果现在里面有"world",需要给集合中添加一个新的"JavaEE"元素!
packagecom.qf.iterator_02;
importjava.util.ArrayList;
importjava.util.Collection;
importjava.util.Iterator;
importjava.util.List;
/**
* 需求:
* 有一个Collection集合,存储一些不重复的String元素,如果现在里面有"world",需要给集合中
* 添加一个新的"JavaEE"元素!
*
* 分析:
* 1)创建Collection,模拟存储一些字符串,里面就包含"world"
* 2)获取Collection集合迭代器,遍历元素,
* 3)判断,如果这里面存在"world",然后添加"JavaEE"
*
*
* 出现了异常"ConcurrentModificationException":并发修改异常
*
* 什么叫并发:在某个时间点上同时进行!
* 在集合这块出现ConcurrentModificationException原因:
* 当使用迭代器去遍历元素的时候,同时不能使用集合对象去操作(修改或添加...)元素,就会出现这个异常!
* 因为,迭代器在遍历元素的时候,集合添加一个新的元素,迭代器不知道!
* 解决方案:
*
* Collection没有直接操作----->子接口List特有功能(ListIterator:列表迭代器/List集合普通for+size()+get(int index))
* 1)集合遍历,集合添加
* 2)迭代器遍历,迭代器遍历
*
*
*/
publicclassCollectionDemo2 {
publicstaticvoidmain(String[] args) {
//1)创建Collection,模拟存储一些字符串,里面就包含"world"
Collection<String>c=newArrayList<>() ;
// List<String> c = new ArrayList<>() ;
c.add("hello") ;
c.add("world") ;
c.add("android") ;
c.add("ios") ;
//2)获取Collection集合迭代器,遍历元素,
Iterator<String>it=c.iterator() ; //接口多态 通过ArrayList的内部类Itr实现迭代器中的方法
while(it.hasNext()){
Strings=it.next();
//判断,如果这里面存在"world",然后添加"JavaEE
if("world".equals(s)){
c.add("JavaEE") ;
}
}
System.out.println(c);
}
}
增强for
packagecom.qf.iterator_02;
/**
* Jdk5新特性:<泛型>,增强for,可变参数,静态导入(导入到方法级别:方法必须静态)...
*
*
* 增强for:是在集合/数组中存储的引用类型中使用居多,代替集合迭代器的,简化书写代码
* 格式:
* for(集合中存储的数据类型 变量名 : 集合对象){
* 使用这个变量名即可;
* }
*
* 注意:
* 要使用增强for遍历集合,集合对象不能null;
* 防止空指针异常,在使用增强for之前,对集合进行非空判断!
*
*/
importjava.util.ArrayList;
importjava.util.Collection;
import staticjava.lang.Math.abs;//静态导入
publicclassForDemo {
publicstaticvoidmain(String[] args) {
//使用java.lang.Math---abs(double /int )求绝对值
// System.out.println(Math.abs(-100));
//System.out.println(abs(-20));
Collection<String>c=newArrayList<>() ;
c.add("hello") ;
c.add("world") ;
c.add("JavaEE") ;
c.add("mysql") ;
//c = null ;
/*
for(集合中存储的数据类型 变量名 : 集合对象){
使用这个变量名即可;
}
*/
for(Strings:c){//增强for替代迭代器
//如果这个有"world"元素,添加一个新的元素"go"
/*if("world".equals(s)){ 并发修改异常:ConcurrentModificationException
c.add("go") ; //迭代器遍历元素,不能使用集合添加
}*/
System.out.println(s);
}
System.out.println(c) ;
}
/* public static void abs(){//如果自定义的方法跟静态导入的方法名一致,导入的方法必须加入它的类的全限定名称区分
}*/
}
packagecom.qf.iterator_02;
importcom.qf.iterator_01.Student;
importjava.util.ArrayList;
importjava.util.Collection;
/**
* 使用Collection存储4个学生,学生有姓名,年龄,使用增强for遍历集合!
* for(集合中存储的数据类型 变量名 : 集合对象){
* 使用这个变量名即可;
* }
*/
publicclassTest {
publicstaticvoidmain(String[] args) {
//创建一个Collection集合
Collection<Student>c=newArrayList<>() ;
//创建学生对象
Students1=newStudent("宋江",45) ;
Students2=newStudent("西门庆",35) ;
Students3=newStudent("武大郎",30) ;
Students4=newStudent("晁盖",36) ;
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
//增强for
for (Studentstudent : c) {
System.out.println(student.getName()+"---"+student.getAge());
}
}
}
使用Collection<String>,使用ArrayList具体的子类,添加重复的String类型数据,保证元素唯一
packagecom.qf.iterator_02;
importjava.util.ArrayList;
importjava.util.Collection;
/**
* 使用Collection<String>,使用ArrayList具体的子类,添加重复的String类型数据,保证元素唯一
*
*/
publicclassTest2 {
publicstaticvoidmain(String[] args) {
//创建Collection
Collection<String>c=newArrayList<>() ;
c.add("hello") ;
c.add("hello") ;
c.add("world") ;
c.add("javaee") ;
c.add("world") ;
c.add("android") ;
c.add("android") ;
c.add("javaee") ;
//新建一个空集合思想
Collection<String>newColl=newArrayList<>() ;
//然后:去遍历以前的集合,获取所有的元素
//在新集合中判断,是否包含这个以前的元素,如果不包含,把这个元素添加新集合中!
for(Strings :c){
//判断
if(!newColl.contains(s)){//不包含
/**
* ArrayList里面的contains底层依赖Object的equals方法,由于现在存String类型
* String类型重写了Object的equals比较的是两个字符串内容是否相同,相同只存储一个!
*/
newColl.add(s) ;
}
}
//只要去遍历新集合
for(Strings:newColl){
System.out.println(s);
}
}
}
packagecom.qf.iterator_02;
importcom.qf.iterator_01.Student;
importjava.util.ArrayList;
importjava.util.Collection;
/**
* Collection<Student>,使用ArrayList具体的子实现类,保证Student对象唯一!
* 去重(学生的成员信息相同,则是同一个人)
*
* ArrayList集合的contains()方法依赖于Object的equals方法,底层实现的"==",比较的是地址值是否相同,下面9个学生都new出来的
* 地址值不相同,都添加到集合中
* 在ArrayList存储自定义类型,要保证元素唯一,必须重写equals和hashCode方法
*/
publicclassTest3 {
publicstaticvoidmain(String[] args) {
Collection<Student>c=newArrayList<>() ;
//创建学生对象
Students1=newStudent("曹操",45) ;
Students2=newStudent("周瑜",20) ;
Students3=newStudent("刘备",35) ;
Students4=newStudent("关羽",32) ;
Students5=newStudent("张飞",30) ;
Students6=newStudent("张飞",30) ;
Students7=newStudent("高圆圆",44) ;
Students8=newStudent("高圆圆",44) ;
Students9=newStudent("高圆圆",35) ;
//添加
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
c.add(s6) ;
c.add(s7) ;
c.add(s8) ;
c.add(s9) ;
//新建空的集合
Collection<Student>newColl=newArrayList<>() ;
//遍历以前的集合
for(Students:c){
//新集合中判断,如果包含这个学生对象,就添加新集合中
if(!newColl.contains(s)){
newColl.add(s) ;
}
}
//遍历新集合
for(Studentstudent:newColl){
System.out.println(student.getName()+"---"+student.getAge());
}
}
}
使用List<String>,使用ArrayList具体的子类,添加重复的String类型数据,保证元素唯一(不能新建集合!)
package com.qf.test_03;
import java.util.ArrayList;
import java.util.List;
/**
*使用List<String>,使用ArrayList具体的子类,
* 添加重复的String类型数据,保证元素唯一(不能新建集合!)
*
* 分析:
* 1)接口多态:List接口指向 ArrayList 或者创建具体子实现类ArrayList<String>
* 2)存储重复的String
* 3)遍历List ,获取到每一个元素
* 4)可以借助选择排序的思想:
* 使用第一个角标对应的元素依次和后面的元素比较,将后面的元素删除,角标--
*/
public class ArrayListTest {
public static void main(String[] args) {
//创建List:可以重复
List<String> list = new ArrayList<>() ;
list.add("hello") ;
list.add("hello") ;
list.add("world") ;
list.add("hello") ;
list.add("javaee") ;
list.add("javaee") ;
list.add("android") ;
list.add("android") ;
list.add("ios") ;
list.add("ios") ;
//List集合:特有遍历方式 : size()获取集合长度 + list集合对象.get(角标)--->获取元素
//选择排序的思想
for(int x = 0 ; x < list.size()-1; x++){//比较次数
//获取到了所有元素
//使用第一个角标对应的元素依次和后面的元素比较,将后面的元素删除,角标--
for(int y = x +1 ; y < list.size() ; y ++){
if(list.get(y).equals(list.get(x))){
//将后面的元素干掉
list.remove(y) ; //通过角标删除元素
y-- ;
}
}
}
//遍历集合
for(String s:list){
System.out.println(s);
}
}
}
list集合特点
package com.qf.list_04;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/**
* List集合特点:
* 元素有序(存储和取出一致),而且元素可以重复!
* Set集合:
* 元素唯一的,无序(存储和取出不一致)
*
*List集合是Collection集合的子接口,它集合遍历方式:
* 1)Collection的Object[] toArray()
* 2)Collection的Iterator iterator() ;
* 3)使用size()+ 存储的数据类型 get(int index)通过角标获取元素内容 :普通for循环格式
* 4)ListIterator<E> listIterator()List集合的专有遍历方式 :列表迭代器
* 5)增强for循环
*
*
*/
@SuppressWarnings("all") //压制所有警告 "jdk提供注解"
public class ListDemo {
public static void main(String[] args) {
//创建List集合
List<String> list = new ArrayList<>() ;
list.add("hello") ;
list.add("world") ;
list.add("JavaEE") ;
list.add("android") ;
list.add("ios") ;
//3)4)5)特有方式
//使用size()+ 存储的数据类型 get(int index)通过角标获取元素内容 :普通for循环格式
for(int x = 0 ; x < list.size() ; x++){
//通过x角标值获取元素内容
String s = list.get(x);
System.out.println(s);
}
System.out.println("--------------------------------------------------") ;
//ListIterator<E> listIterator()List集合的专有遍历方式 :列表迭代器
ListIterator<String> lit = list.listIterator();//获取列表迭代器
//ListIterator--->接口提供一些方法
//boolean hasNext():判断是否有下个元素
//E next():获取下一个元素
while(lit.hasNext()){
String s = lit.next();
System.out.println(s);
}
System.out.println("--------------------------------");
//列表迭代器提供了一些功能,进行逆序遍历(前提必须有上面的正向遍历)
//boolean hasPrevious():判断是有上一个元素
//E previous():获取上一个元素
while(lit.hasPrevious()){
String previous = lit.previous();
System.out.println(previous);
}
System.out.println("---------------------------------------------------") ;
//增强for (推荐)
for(String s:list){
System.out.println(s) ;
}
}
}
package com.qf.list_04;
/**
* @author 高圆圆
* @date 2023/3/17 15:37
*/
public class Student {
private String name ;
private int age ;
public Student() {
}
public Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.qf.list_04;
import java.util.ArrayList;
/**
* 需求:
* * 三个Java班级:每一个班级看成ArrayList
* * 三个班级组成一个大的集合ArrayList<ArrayList<Student>>,
* * 第一个班级存储
* * 高圆圆 22
* * 赵又廷 25
* * 第二个班级存储
* * 张三丰 50
* * 令狐冲 35
* * 第三个班级存储
* * 孙悟空 32
* * 唐僧 40
* *
* * 去遍历大的集合ArrayList<ArrayList<Student>>,打印学生信息
*/
public class ArrayListTest {
public static void main(String[] args) {
//先创建一个大的集合
ArrayList<ArrayList<Student>> bigArray = new ArrayList<>() ;
//第一个班级
ArrayList<Student> firstArray = new ArrayList<>() ;
Student s1 = new Student("高圆圆",22) ;
Student s2 = new Student("赵又廷",25) ;
firstArray.add(s1) ;
firstArray.add(s2) ;
//将firstArray添加到大集合中
bigArray.add(firstArray) ;
//第二个班级
ArrayList<Student> secondArray = new ArrayList<>() ;
Student s3 = new Student("张三丰",50) ;
Student s4 = new Student("令狐冲",35) ;
secondArray.add(s3) ;
secondArray.add(s4) ;
//将secondArray添加到大集合中
bigArray.add(secondArray) ;
//第二个班级
ArrayList<Student> thirdArray = new ArrayList<>() ;
Student s5 = new Student("孙悟空",32) ;
Student s6 = new Student("唐僧",40) ;
thirdArray.add(s5) ;
thirdArray.add(s6) ;
//将thirdArray添加到大集合中
bigArray.add(thirdArray) ;
//ArrayList<ArrayList<Student>>
//遍历大集合
System.out.println("学生信息是:\t");
for(ArrayList<Student> array:bigArray){
//每一个ArrayList集合里面存储的学生对象
for(Student s: array){
System.out.println(s.getName()+"\t"+s.getAge());
}
}
}
}
List集合常用三个子实现类特点:
List集合常用三个子实现类特点:
实际需求:单线程中,使用List完成一些事情,没有明确规定具体使用哪个实现类;默认使用ArrayList集合!
默认:ArrayList
底层数据结构是数组-->查询快,增删慢! (数组,通过整数索引查询)
元素查找: 顺序查找,二分搜索(折半查找),哈希查找
43,50,66,70,---->哈希查询,哈希表的长度10
43 % 10 = 3
线程角度:
线程不安全的类,是一个不同步,执行效率高!
底层扩容机制1.5倍
Vector
底层数据结构是数组-->查询快,增删慢!
线程角度:
线程安全的类,是同步的,执行效率低! 多线程环境下使用居多,单线程使用ArrayList代替Vector
LinkedList
底层数据是链表, 查询慢,增删快
线程角度:
线程不安全的类,不同步的,执行效率高!
迭代器底层原理:就是ArrayList集合的内部类实现Itr间接实现了两个功能!
//体现结构
//迭代器
interface Iterator<E>{
boolean hasNext() ;判断是否有下一个可以迭代的元素
E next() ;获取下一个元素
}
interface Iterable<T>{
Iterator<E> iterator();
}
interface Collection<E> extends Iterable {
Iterator<E> iterator();
}
interface List<E> extends Collection<E>{
Iterator<E> iterator();
}
//具体的子实现类
public class ArrayList<E> implements List<E>{
public Iterator<E> iterator() {
return new Itr();
}
//私有的成员内部类Itr
private class Itr implements Iterator<E> {
boolean hasNext(){
}
Object next(){
...
}
}
}
原理:就是ArrayList集合的内部类实现Itr间接实现了两个功能!
day22
使用List集合解决并发修改异常
packagecom.qf.list_01;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.ListIterator;
/**
* 使用List集合解决并发修改异常
* List有特有方式:
* size()获取集合长度 结合 Object get(int index)通过索引值获取对应的内容
* 特有添加元素的方式:
* void add(int index,E element):在指定位置处,添加指定的元素!
*
*
* 使用Collection<String>,如果Collection集合中存储有"world"元素,给集合中新添加一个元素--->
* 出现ConcurrentModificationException
* 出现并发修改异常的原因:使用迭代器去遍历元素的时候,不能同时集合操作元素;
* 解决方案:
* 1)集合遍历,集合添加
* 2)迭代器遍历,迭代器添加元素
*
* List继承Collection--->Iterator是Collection的专有迭代器,没有提供添加功能,而
* List集合专有遍历方式ListIterator:列表迭代器
*/
publicclassListDemo {
publicstaticvoidmain(String[] args) {
//使用List集合存储String
List<String>list=newArrayList<>() ;
list.add("hello") ;
list.add("world") ;
list.add("javaee") ;
// 1)集合遍历,集合添加
//size()获取集合长度 结合 Object get(int index)通过索引值获取对应的内容
/* for(int x = 0 ; x < list.size() ; x++){
String s = list.get(x);
//判断
if("world".equals(s)){
list.add("go") ; //add()方法继承自 Collection的方法
}
}*/
//2)迭代器遍历元素,迭代器添加元素
// ListIterator<E> listIterator()
//ListIteratr--->void add(E e)将指定的元素插入列表
ListIterator<String>lit=list.listIterator(); //ListItr extends Itr :都是ArrayList的内容类
while(lit.hasNext()){
//获取下一个元素
Strings=lit.next();
//判断:如果s是"world",添加一个新的"go"
if("world".equals(s)){
lit.add("go") ;
}
}
//输出list
System.out.println(list);
}
}
Vector集合
packagecom.qf.list_01;
importjava.util.Enumeration;
importjava.util.Vector;
/**
* Vector:底层数组,查询快,增删慢,线程安全的,执行效率低!
*
*
* Vector集合的特有功能:
* 遍历方式:Collection的Object[] toArray()
* Collection的Iterator iterator()
* List接口提供的 size()+get(int index)
* List接口提供的ListIterator listiterator()
* 特有遍历方式
* public Enumeration<E> elements()--->相当于集合的迭代器
* * Enumeration接口:枚举组件
* boolean hasMoreElements()---->相当于boolean hasNext()
* E nextElement() ---->相当于E next()
*
* public E elementAt(int index)--->相当于List的get(int index)+size方法相结合
*
* 增强for
*
* 添加:
* public void addElement(E obj)--->相当于List的add()
* public E elementAt(int index)--->相当于List的get(int index)
*
*
*/
publicclassVectorDemo {
publicstaticvoidmain(String[] args) {
//创建Vector集合
Vector<String>v=newVector<>() ;
//public void addElement(E obj)--->相当于List的add()
v.addElement("hello");
v.addElement("world");
v.addElement("javaee");
v.addElement("mysql");
// 遍历
//public E elementAt(int index)--->相当于List的get(int index)+size方法相结合
for(intx=0 ; x<v.size() ; x++){
Strings=v.elementAt(x);
System.out.println(s);
}
System.out.println("----------------------------------------") ;
/**
* public Enumeration<E> elements()--->相当于集合的迭代器
* Enumeration接口:枚举组件
* boolean hasMoreElements()---->相当于boolean hasNext()
* E nextElement() ---->相当于E next()
*/
/* for(Enumeration<String> en = v.elements(); en.hasMoreElements();){
System.out.println(en.nextElement());
}*/
Enumeration<String>en=v.elements() ;
while(en.hasMoreElements()){
Strings=en.nextElement();
System.out.println(s);
}
System.out.println("-----------------------------------") ;
for(Strings:v){
System.out.println(s);
}
}
}
LinkedList的特有方法:
packagecom.qf.list_01;
importjava.util.LinkedList;
/**
* LinkedList的特有方法:
* public void addFirst(E e) :在链表开头插入元素
* public void addLast(E e) :在链表末尾插入元素
* public E removeFirst(): 删除链表开头的第一个元素并返回该元素
* public E removeLast()从此列表中删除并返回最后一个元素。
* public E getFirst():返回链表头元素
* public E getLast():返回链表链尾元素
*
*
* 需求:
* 利用LinkedList模拟栈的结构特点,先进后出
*
* 自定义类--->里面使用到LinkedList的特有功能
* 方法add()--->linkedList的addFirst()
* get()--->获取元素: LinkedList的removeFirst()删除并返回
* 自定义一个方法isEmpty()--->判断LinkedList是否为空
*
* 在定义一个测试类---完成上面类的功能测试
*
*/
publicclassLinkedListDemo {
publicstaticvoidmain(String[] args) {
//创建LinkedList集合
LinkedList<String>link=newLinkedList<>() ;
//添加元素
link.addFirst("hello") ;
link.addFirst("world") ;
link.addFirst("javaee") ;
/* for(String s:link){
System.out.println(s);
}*/
System.out.println(link);
//删除
System.out.println(link.removeFirst()) ;
System.out.println(link);
//获取
System.out.println(link.getFirst());
System.out.println(link.getLast());
}
}
Set接口特点:
packagecom.qf.set_02;
importjava.util.HashSet;
/**
* Set接口特点:
* 无序(存储和取出不一致),不能保证迭代次序,但是可以唯一!
* HashSet<E> : 存储和取出,保证元素唯一!
* ---底层是HashMap实例(哈希表)
* TreeSet<E> : 存储和取出,同时需要进行排序的取出!
* ---底层是依赖TreeMap实例(红黑树结构)
*/
publicclassHashSetDemo {
publicstaticvoidmain(String[] args) {
//创建HashSet集合对象
HashSet<String>hs=newHashSet<>() ;
hs.add("hello") ;
//System.out.println("hello".hashCode());
hs.add("hello") ;
hs.add("hello") ;
hs.add("world") ;
hs.add("world") ;
hs.add("world") ;
hs.add("JavaEE") ;
hs.add("JavaEE") ;
//遍历
for(Strings:hs){
System.out.println(s);
}
}
}
packagecom.qf.set_02;
importjava.util.HashSet;
/**
* 使用HashSet存储一些学生(姓名,年龄),让你保证学生对象唯一!
* 自定义类型必须重写HashCode和equals方法,保证自定义类的对象唯一!
*/
publicclassHashSetTest {
publicstaticvoidmain(String[] args) {
HashSet<Student>hs=newHashSet<>() ;
//创建学生对象
Students1=newStudent("高圆圆",44) ;
Students2=newStudent("高圆圆",44) ;
Students3=newStudent("高圆圆",35) ;
Students4=newStudent("文章",35) ;
Students5=newStudent("文章",35) ;
Students6=newStudent("王宝强",30) ;
Students7=newStudent("王宝强",30) ;
//添加
hs.add(s1) ;
hs.add(s2) ;
hs.add(s3) ;
hs.add(s4) ;
hs.add(s5) ;
hs.add(s6) ;
hs.add(s7) ;
//遍历
for(Students:hs){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
packagecom.qf.set_02;
/**
* 学生类
*/
publicclassStudent {
privateStringname ;
privateint age ;
publicStudent() {
}
publicStudent(Stringname, intage) {
this.name=name;
this.age=age;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name=name;
}
publicintgetAge() {
returnage;
}
publicvoidsetAge(intage) {
this.age=age;
}
@Override
publicStringtoString() {
return"Student{"+
"name='"+name+'\''+
", age="+age+
'}';
}
@Override
publicbooleanequals(Objecto) {
if (this==o) returntrue;
if (o==null||getClass() !=o.getClass()) returnfalse;
Studentstudent= (Student) o;
if (age!=student.age) returnfalse;
returnname.equals(student.name);
}
@Override
publicinthashCode() {
intresult=name.hashCode();
result=31*result+age;
returnresult;
}
}
Hashset集合的add方法
publicclassHashSet<E> implementsSet<E>{
//transient:io流 :map属性不参与序列化(io流相关的)
privatetransientHashMap<E,Object>map;
privatestaticfinalObjectPRESENT=newObject();
publicHashSet() {
//创建了一个HashMap集合
map=newHashMap<>();
}
publicbooleanadd(Ee) { //"添加的那些元素"
//map集合的添加方法put(k,v)
//e:那些元素,
returnmap.put(e, PRESENT)==null;
}
}
//HashMap集合
classHashMap<K,V>implementsMap<K,V>{
publicVput(Kkey, Vvalue) { //key:传过来的元素,v是常量
returnputVal(hash(key), key, value, false, true);
}
//1)"hello","hello","hello","world"...
staticfinalinthash(Objectkey) { //将key那些元素传进来
inth; //初始化h
return (key==null) ?0 : (h=key.hashCode()) ^ (h>>>16);
}
//2)执行putVal()
//jdk8以后:数组+链表+红黑树结构
finalVputVal(inthash, Kkey, Vvalue, booleanonlyIfAbsent,
booleanevict) {
Node<K,V>[] tab; Node<K,V>p; intn, i;
if ((tab=table) ==null|| (n=tab.length) ==0)
n= (tab=resize()).length;
if ((p=tab[i= (n-1) &hash]) ==null)
tab[i] =newNode(hash, key, value, null);
else {
Node<K,V>e; Kk;
if (p.hash==hash&&
((k=p.key) ==key|| (key!=null&&key.equals(k))))
e=p;
elseif (pinstanceofTreeNode)
e= ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (intbinCount=0; ; ++binCount) {
if ((e=p.next) ==null) {
p.next=newNode(hash, key, value, null);
//当链表结构取到7的时候,开始进行"树化"操作
if (binCount>=TREEIFY_THRESHOLD-1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash==hash&&
((k=e.key) ==key|| (key!=null&&key.equals(k))))
break;
p=e;
}
}
if (e!=null) { // existing mapping for key
VoldValue=e.value;
if (!onlyIfAbsent||oldValue==null)
e.value=value;
afterNodeAccess(e);
returnoldValue;
}
}
++modCount;
if (++size>threshold)
resize();
afterNodeInsertion(evict);
returnnull;
}
}
HashSet集合依赖于HashMap---->间接与hash()---->依赖于hashCode(),put()方法--->equals方法
存储String类型,字符串重写过来equals和hashCode(),元素唯一!
TreeSet<E>有两种排序方式
packagecom.qf.set_03;
importjava.util.TreeSet;
/**
*TreeSet<E>有两种排序方式
* 自然排序:
* public TreeSet():使用自然排序,当前里面存储的类型必须实现Comparable
* 比较器排序
*/
publicclassTreeSetDemo {
publicstaticvoidmain(String[] args) {
//创建一个TreeSet集合
// public TreeSet():
/* TreeSet<Integer> ts = new TreeSet<>() ;
ts.add(20) ;
ts.add(17) ;
ts.add(19) ;
ts.add(22) ;
ts.add(23) ;
ts.add(22) ;
ts.add(18) ;
ts.add(19) ;
ts.add(16) ;
ts.add(24) ;
//遍历
for(Integer i :ts){
System.out.println(i);
}
*/
TreeSet<String>ts=newTreeSet<>() ;
ts.add("world") ;
ts.add("java") ;
ts.add("abc") ;
ts.add("bcd") ;
ts.add("defg") ;
ts.add("defg") ;
ts.add("wyz") ;
for(Strings:ts){
System.out.println(s);
}
}
}
packagecom.qf.set_03;
importjava.util.TreeSet;
/**
* 使用TreeSet集合存储学生类型Student(姓名,年龄),取出学生的信息;
* 自然排序:TreeSet<E>() 无参构造方法
*
* 需求:
* 主要排序条件:
* 需要按照学生的年龄从小到大排序!
*
*
* 键盘录入5个学生的语文成绩,数学成绩,英语成绩,以及姓名,按照总分从高到低排序!
*/
publicclassTreeSetTest {
publicstaticvoidmain(String[] args) {
TreeSet<Student>ts=newTreeSet<>() ; //无参构造方法
Students1=newStudent("gaoyuanyuan",35) ;
Students2=newStudent("gaoyuanyuan",35) ;
Students3=newStudent("gaoyuanyuan",25) ;
Students4=newStudent("wenzhang",38) ;
Students5=newStudent("mayili",45) ;
Students6=newStudent("yaodi",20) ;
Students7=newStudent("baoqiang",32) ;
Students8=newStudent("mabaoguo",65) ;
Students9=newStudent("zhangsanfeng",65) ;
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
ts.add(s9) ;
//遍历
for(Students:ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
packagecom.qf.set_03;
importjavax.xml.stream.events.StartDocument;
/**
* 学生类
*/
//必须实现接口Compareable,自然排序
publicclassStudent implementsComparable<Student>{
private Stringname ;
privateintage ;
publicStudent() {
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name=name;
}
publicintgetAge() {
returnage;
}
publicvoidsetAge(intage) {
this.age=age;
}
publicStudent(Stringname, intage) {
this.name=name;
this.age=age;
}
@Override
publicStringtoString() {
return"Student{"+
"name='"+name+'\''+
", age="+age+
'}';
}
//重写
@Override
publicintcompareTo(Students) { //存储到每一个学生对象
//主要排序条件:
// 需要按照学生的年龄从小到大排序!
intnum=this.age-s.age ;
//int num = s.age - this.age ;
//年龄相同,比较姓名的内容是否相同
intnum2=(num==0)?(this.name.compareTo(s.name)):num ;
returnnum2;
}
}
Treeset的add方法
class TreeSet<E> implemnts Set{
private transient NavigableMap<E,Object> m;
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
}
class TreeMap<K,V> implements NavigableMap<K,V>{
public V put(K key, V value) { //K key---->s1---s8学生对象 类型Student
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths //比较器排序/自然排序
Comparator<? super K> cpr = comparator; //比较器排序
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException(); //元素null,空指针异常
@SuppressWarnings("unchecked") //压制警告
//将key的类型
<?>:任意Java类型
<? extends E> 向下限定 E这个类型或者它的子类
<? super E>:向上限定 E这个类型或者它的父类
//K--->Student类型--->
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left; //左子节点
else if (cmp > 0) //右子节点
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
}
要进行自然排序,TreeSet存储类型必须实现接口Compareable接口,重写compareTo方法,否则报错!