行业知识
Java入门
2026-11-03 22:59:52
来源:互联网转载
文章目录
- Java SE
- private、protect、default的区别
- this的用法
- 继承extends及覆盖重写Override
- super的用法
- 接口interface及implements
- static的用法
- static修饰成员变量
- static 修饰成员方法
- 多态
- 向上转型和向下转型
- instanceof用法
- 接口可作为方法的参数
- final的用法
- 导包import
- 内部类和外部类
- 局部内部类
- 匿名内部类
- toString
- equals
- Data类及其方法
- DataFormat类及其SimpleDataFormat子类
- 测试
- Calendar类及其方法
- System类及其方法
- StringBuilder及其方法
- 包装类Integer及其方法
- Collection接口及其方法
- 迭代器Iterator
- 增强for循环
- 泛型
- 泛型类
- 泛型接口
- 测试
- 通配符 ? 的用法
- 泛型的上限限定和泛型的下限限定
- 斗地主小游戏
- List集合及其方法
- LinkedList集合及其方法
- Set集合及其方法
- HashSet集合及其方法
- 哈希值
- 小测试
- LinkedHashSet集合及其方法
- 可变参数
- Collection集合工具类及其方法
- Comparable接口
- 小测试
- Map集合及其方法
- Map集合的遍历方式
- 第一种遍历方式:通过键找值(keySet)的方法
- 第二种遍历方式:使用Entry对象遍历
- LinkedHashMap集合
- Hashtable集合
- 小测试
- JDK9新特性
- 斗地主综合案例:有序版本
- Throwable类
- throw关键字用法
- 异常处理
- 异常的注意事项
- 子父类的异常
- 自定义异常类
- 小测试
- 多线程Thread
- 创建多线程的第一种方式:创建Thread类的子类
- 获取线程的名称
- 设置线程的名称
- sleep方法
- 创建多线程的第二种方式:实现Runnable接口
- 匿名内部类方式实现线程的创建
- 主线程
- Runable接口演示实例1(有bug)
- Runable接口演示实例2
- 解决线程安全问题的第一种方案:synchronized同步代码块
- 解决线程安全问题的第二种方案:使用同步方法
- 解决线程安全问题的第三种方案:使用lock锁
- synchronized同步与互斥实例
- 等待唤醒案例:线程之间的通信
- Object类中的wait和notify方法及notifyAll方法
- 线程池
- Lambda表达式
- 小测试
- 实例1
- 实例2
- 实例3
- File类及其方法
- File类获取功能的方法
- File判断功能的方法
- File类创建删除功能的方法
- File类遍历(文件夹)目录功能
- 递归:方法自己调用自己
- 过滤器FileFilter类及其方法
- OutputStream:字节输出流
- FileOutputStream:文件字节输出流
- InputStream:字节输入流
- FileInputStream:文件字节输入流
- Reader:字符输入流
- FileReader:文件字符输入流
- Writer:字符输出流
- FileWriter:文件字符输出流
- flush方法和close方法的区别
- 在jdk1.7之前使用try catch finally 处理流中异常
- JDK7新特性
- Properties集合
- BufferedOutputStream:字节缓冲输出流
- BufferedInputStream:字节缓冲输入流
- 文件复制练习:一读一写
- BufferedWriter:字符缓冲输入流
- BufferedReader:字符缓冲输出流
- Split方法
- OutputStreamWrite:是字符通向字节流的桥梁
- InputStreamReader: 是字节通向字符流的桥梁
- 练习:转换文件编码
- Serializable接口:也叫标记型接口
- ObjectOutputStream: 对象的序列化流
- ObjectInputStream:对象的反序列化流
- 练习:序列化集合
- PrintStream:打印流
Java SE
黑马程序员
private、protect、default的区别
- private:只能被自己访问和修改。
- protected:自身,子类及同一个包中类可以访问。
- default(默认):同一包中的类可以访问,声明时没有加修饰符,认为是friendly。
this的用法
- this只能调用本类的成员方法或成员变量
//静态当中不能用this关键字//this代表当前对象,而静态方法通过类名称调用package com.xpzt.day07.demo05;public class Zi extends Fu { int num = 20; public Zi() { this(1); System.out.println("无参构造方法"); } public Zi(int num) { this(1, 2); System.out.println("一个参数构造方法"); } public Zi(int num1, int num2) { //这里有一个隐含的super(); System.out.println("两个参数构造方法"); } public void method() { int num = 10; System.out.println(num); System.out.println(super.num);//11 super.methodB();//父类 methodB();//子类 this.methodB();//子类 -- 就是为了容易看出是子类的成员方法 System.out.println(this.num); //this是调用本类成员变量或方法 } @Override public void methodB() { super.methodB(); System.out.println("子类方法B执行!"); }}继承extends及覆盖重写Override
- 子类可以继承父类的成员方法及成员变量并在父类的基础上加以延伸
public class NewPhone extends Phone { @Override public void show() { super.show();//继续用父类的 System.out.println("姓名"); System.out.println("归属地"); }}super的用法
- 子类可以用super调用父类的成员方法或成员变量
public class Zi extends Fu { int num = 10; public void method() { int num = 20; System.out.println(num); //this是指本类的成员变量 System.out.println(this.num); System.out.println(super.num); }}接口interface及implements
- 接口是默认使用抽象方法的,使用其他类实现接口类
public class MyInterfaceAbstractImpl implements MyInterfaceAbstract { @Override public void methodAbs1() { System.out.println("这是第一个方法"); } @Override public void methodAbs2() { System.out.println("这是第二个方法"); } @Override public void methodAbs3() { System.out.println("这是第三个方法"); } @Override public void methodAbs4() { System.out.println("这是第四个方法"); }}static的用法
static修饰成员变量
- 静态变量的数据被本类中所有实例对象所共享
- 如果该静态变量的访问权限高于private,则该静态变量可通过“类名.变量名”直接访问
static 修饰成员方法
- 在类中,被static修饰的方法称作静态方法。同静态变量一样,如果该静态方法的访问权限高于private,则该静态方法可通过“类名.方法名/接口名.方法名”直接调用,而不需要创建对象调用
多态
-
使用多态的写法,左侧父类的引用,指向了右侧子类的对象
-
成员变量:编译看左边,运行看左边
-
成员方法:编译看左边,运行看右边
public class Fu { int num = 10; public void showNum() { System.out.println(this.num); } public void method(){ System.out.println("父类方法"); } public void methodFu(){ System.out.println("父类特有方法"); }}public class Zi extends Fu { int num = 20; @Override public void showNum() { System.out.println(this.num); } @Override public void method(){ System.out.println("父类方法"); } public void methodZi(){ System.out.println("子类特有方法"); }}public class Demo01MultiField { public static void main(String[] args) { //成员变量:编译看左边,运行看左边 //成员方法:编译看左边,运行看右边 Fu obj = new Zi(); System.out.println(obj.num);//父类 -- 看等号左边是谁,优先用谁,没有则向上找 obj.showNum();///父类 -- 看等号右边是谁,优先用谁,没有则向上找 }}public class Demo02MultiMethod { public static void main(String[] args) { //成员变量:编译看左边,运行看左边 //成员方法:编译看左边,运行看右边 Fu obj=new Zi();//多态 obj.method();//父子若有,优先用子类 obj.methodFu();//子类没有,父类有,向上找到父类 }}向上转型和向下转型
public class Demo01Main { public static void main(String[] args) { //对象的向上转型就是,父类引用指向子类对象 Animal animal = new Cat(); animal.eat(); //向下转型 -- “还原”动作 Cat cat = (Cat) animal; cat.catchMouse(); //错误向下转型写法 //本来new的是猫,现在非要当成狗 //ClassCastException// Dog dog = (Dog) animal; }}instanceof用法
- 向下转型一定要进行instanceof判断,否则可能发生类转换异常
public class Demo02Instanceof { public static void main(String[] args) { Animal animal = new Cat(); animal.eat(); //向下转型一定要进行instanceof判断,否则可能发生类转换异常 if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.catchMouse(); } if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.watchHouse(); } giveAPet(new Dog()); } public static void giveAPet(Animal animal) { //判断父类引用animal本来是不是Cat if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.catchMouse(); } //判断父类引用animal本来是不是Dog if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.watchHouse(); } }}接口可作为方法的参数
public interface USC { public abstract void open();//打开设备 public abstract void close();//关闭设备}//鼠标就是一个USC设备public class Mouse implements USC { @Override public void open() { System.out.println("打开鼠标"); } @Override public void close() { System.out.println("关闭鼠标"); } public void click() { System.out.println("点击鼠标"); }}//键盘就是一个USC设备public class KeyBoard implements USC { @Override public void open() { System.out.println("打开键盘"); } @Override public void close() { System.out.println("关闭键盘"); } public void type() { System.out.println("键盘输入"); }}public class Computer { public void powerOn() { System.out.println("笔记本开机"); } public void powerOff() { System.out.println("笔记本关机"); } //使用USC设备的方法, 使用接口作为方法的参数 public void useDevice(USC usc) {//USC usc=new Mouse()/new KeyBoard() //成员变量:编译看左边,运行看左边 //成员方法:编译看左边,运行看右边 usc.open();//打开设备 if (usc instanceof Mouse) { //先判断 Mouse mouse = (Mouse) usc;//向下转型 mouse.click(); } else if (usc instanceof KeyBoard) {//先判断 KeyBoard keyBoard = (KeyBoard) usc;//向下转型 keyBoard.type(); } usc.close();//关闭设备 }}public class Computer { public void powerOn() { System.out.println("笔记本开机"); } public void powerOff() { System.out.println("笔记本关机"); } //使用USC设备的方法, 使用接口作为方法的参数 public void useDevice(US usc) {//USC usc=new Mouse()/new KeyBoard() //成员变量:编译看左边,运行看左边 //成员方法:编译看左边,运行看右边 usc.open();//打开设备 if (usc instanceof Mouse) { //先判断 Mouse mouse = (Mouse) usc;//向下转型 mouse.click(); } else if (usc instanceof KeyBoard) {//先判断 KeyBoard keyBoard = (KeyBoard) usc;//向下转型 keyBoard.type(); } usc.close();//关闭设备 }}final的用法
- final关键字修饰类, 修饰字段, 修饰方法,修饰局部变量,修饰方法的形参
- final修饰类,表示最终类, 不能被继承,不能作为父类存在
- final修饰方法,不能被覆盖(重写)
- final修饰局部变量, 一旦初始化就不能再修改, 注意final修饰引用类型变量,是指这个变量不能再指向其他对象 , 可以修改它的字段值
- final修饰方法形参, 在方法体中不能修改final参数的值
public class Demo01Final { public static void main(String[] args) { int num1 = 10; System.out.println(num1); final int num2 = 20; System.out.println(num2); //错误写法,"一次赋值,终生不变" //num2 = 10; //正确写法,只要保证有唯一一次赋值就行 final int num3; num3 = 11; //对于基本类型来说,不可改变的是变量的数据不可改变 //对于引用类型来说,不可改变的是变量的地址不可改变 new了之后地址就改变 Student stu1 = new Student("赵丽颖"); System.out.println(stu1.getName()); System.out.println(stu1); stu1 = new Student("霍建华"); System.out.println(stu1.getName()); System.out.println(stu1); System.out.println("==============="); final Student stu2 = new Student("李浩"); System.out.println(stu2.getName()); //不能改变的是地址,但是内容可以改变 //stu2 = new Student("张思"); stu2.setName("李浩浩浩"); System.out.println(stu2.getName()); }}导包import
package com.xpzt.day12.demo02;public class MyClass { public int num = 10; public void method() { System.out.println(num); }}package com.xpzt.day12.demo02;public class MyAnother { public void anotherMethod() { System.out.println((new MyClass()).num); }}package com.xpzt.day12.demo02.sub;//导包MyClassimport com.xpzt.day12.demo02.MyClass;public class MySon extends MyClass { public void methodSon() { System.out.println(super.num); }}package com.xpzt.day12.demo02.sub;//导包MyClassimport com.xpzt.day12.demo02.MyClass;public class Stranger { public void methodStranger() { System.out.println(new MyClass().num); }}内部类和外部类
public class Body {//外部类 public class Heart {//成员内部类 //内部类的方法 public void heat() { System.out.println("心脏跳动,滴滴滴"); System.out.println("我叫:" + name); } } //外部类的成员方法 private String name; //外部类的方法 public void method() { System.out.println("外部类方法"); //使用匿名对象 new Heart().heat(); } public Body(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }}- 内部类和外部类成员变量出现重名,则引用外部类成员变量格式:外部类.this.外部成员变量名
//如果出现了重名 现象,那么格式是 :外部类.this.外部成员变量名public class Outer { int num = 30;//外部成员变量 public class Inner { int num = 20;//内部成员变量 public void method() { int num = 10;//内部类方法的局部变量 System.out.println(num);//局部变量,就近原则 System.out.println(this.num);//内部类的成员变量 System.out.println(Outer.this.num);//外部类的成员变量 } }}- 通过外部类名称.内部类名称 对象名 = new 外部类名称().new内部类名称() 调用内部类方法
public class Body {//外部类 public class Heart {//成员内部类 //内部类的方法 public void heat() { System.out.println("心脏跳动,滴滴滴"); System.out.println("我叫:" + name); } } //外部类的成员方法 private String name; //外部类的方法 public void method() { System.out.println("外部类方法"); //使用匿名对象 new Heart().heat(); } public Body(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }}public class Demo01InnerClass { public static void main(String[] args) { Body body = new Body("陈浩");//外部类对象 //通过外部类对象,调用内部类方法,里面简介在使用内部类Heart body.method(); System.out.println("============="); //使用公式写: //外部类名称.内部类名称 对象名 = new 外部类名称().new内部类名称(); Body.Heart heart = new Body("猪比").new Heart(); heart.heat(); }}局部内部类
- 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是{有效final的}
- 加final关键字或者不加final关键字就赋值唯一一次
public class MyOuter { public void methodOuter() { /*final*/int num; num = 10; class Inner { public void methodInner() { System.out.println(num); } } }}匿名内部类
- 格式:new interface(){ 成员函数 / 覆盖重写成员函数 }
- 匿名内部类.方法(既是匿名内部类,又是匿名对象)
public class DemoMain { public static void main(String[] args) { //使用匿名内部类 MyInterface objA = new MyInterface() { @Override public void method1() { System.out.println("匿名内部类覆盖重写了接口抽象方法 111-A"); } @Override public void method2() { System.out.println("匿名内部类覆盖重写了接口抽象方法 222-A"); } }; objA.method1(); objA.method2(); System.out.println("================================="); //匿名内部类.方法(既是匿名内部类,又是匿名对象) new MyInterface() { @Override public void method1() { System.out.println("匿名内部类覆盖重写了接口抽象方法 111-A"); } @Override public void method2() { System.out.println("匿名内部类覆盖重写了接口抽象方法 222-A"); } }.method1(); //使用了匿名内部类,省略了对象名称,也是匿名对象 new MyInterface() { @Override public void method1() { System.out.println("匿名内部类覆盖重写了接口抽象方法 111-B"); } @Override public void method2() { System.out.println("匿名内部类覆盖重写了接口抽象方法 222-B"); } }.method2(); }}toString
- 看一个类是否重写了toString,直接打印这个类的对象即可,如果没有重写toString方法,那么打印的是对象的地址值
public class Demo01ToString { public static void main(String[] args) { Person person = new Person(); person.setName("李白"); person.setAge(20); //看一个类是否重写了toString,直接打印这个类的对象即可,如果没有重写toString方法,那么打印的是对象的地址值 String p = person.toString(); System.out.println(person); System.out.println(p); }}equals
- 基本数据类型:比较的是值
- 引用数据类型:比较的是两个对象的地址值
import java.util.Objects;public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } //覆盖重写toString方法 @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } //Object类的equals方法,默认比较是两个对象的地址值,没有意义 //覆盖重写equals方法,比较两个对象的属性 @Override public boolean equals(Object obj) { //增加一个判断,如果是this本身,直接返回true,提高程序效率 if (obj == this) { return true; } //增加一个判断,如果传递参数是null,返回false,提高程序效率 if (obj == null) { return false; } //增加一个判断防止类转换异常 if (obj instanceof Person) { // 使用向下转型,将obj强转成Person类 Person p = (Person) obj; //比较两个对象的属性 boolean b = this.name == p.name && this.age == p.age; return b; } return false; }// @Override// public boolean equals(Object o) {// if (// //getClass() != o.getClass()使用反射技术,判断o是不是Person类型 -- 等效于 obj instanceof Person// )// if (o == null || getClass() != o.getClass()) return false;// Person person = (Person) o;// //使用Object类的equals方法,对两个对象进行比较,可以防止空指针异常// return age == person.age && Objects.equals(name, person.name);// } @Override public int hashCode() { return Objects.hash(name, age); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age) { this.name = name; this.age = age; } public Person() { }}public class Demo02Equals { public static void main(String[] args) { Object p1 = new Person("陈浩", 20); System.out.println(p1); Object p2 = new Person("猪比", 22); System.out.println(p2); //equals //基本数据类型:比较的是值 //引用数据类型:比较的是两个对象的地址值 boolean b1 = p1.equals(p2); System.out.println(b1); p1 = p2; boolean b2 = p1.equals(p2); System.out.println(b2); }}Data类及其方法
import java.util.Date;public class Demo02Date { public static void main(String[] args) { demo01(); demo02(); demo03(); } //long getTime() 把日期转换成毫秒值 //相当于System.currentTimeMillis() -- 获取当前系统时间到1970年08:00:00经历了多少毫秒 private static void demo03() { Date date=new Date(); long time = date.getTime(); System.out.println(time); } //Date类带参数构造方法 //Date()传递毫秒值,把毫秒值转换为Date日期 private static void demo02() { Date date = new Date(1608131750052L); System.out.println(date); } //Date类的空参数构造方法 private static void demo01() { Date date = new Date(); System.out.println(date);//获取当前的日期和时间 }}DataFormat类及其SimpleDataFormat子类
import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;/*java.text.DateFormat是日期/时间格式化子类的抽象类作用: 格式化(日期->文本),解析(文本->日期)成员方法: String format(Date date) 按照指定格式,把Date日期,格式化为符合模式的字符串 Date parse(String source) 把符合模式的字符串,解析为Date日期DateFormat是一个抽象类,无法直接创建对象,可以用DateFormat类的子类SimpleDateFormatjava.text.SimpleDateFormat extends DateFormat构造方法: SimpleDateFormat(String pattern) 用给定的模式和默认语言环境的日期格式构造SimpleDateFormat。模式:区分大小写 y 年 M 月 d 天 H 时 m 分 s 秒* */public class Demo01DateFormat { public static void main(String[] args) throws ParseException { demo01(); Demo02(); } /*public Date parse(String source) throws ParseException * parse声明了一个异常叫ParseException * 如果字符串和构造方法的模式不一样,那么程序就会抛出异常*/ private static void Demo02() throws ParseException { DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); //Date parse(String source) 把符合模式的字符串,解析为Date日期 Date date = dateFormat.parse("2020年12月17日 11:27:42"); System.out.println(date); } private static void demo01() { DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date date = new Date(); String time = dateFormat.format(date); System.out.println(date); System.out.println(time); }}测试
import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Scanner;/*使用日期时间相关的API,计算一个人出生了多少天 * */public class Demo02Test { public static void main(String[] args) throws ParseException { //1.使用Scanner获取出生日期 Scanner sc = new Scanner(System.in); System.out.println("请输入出生日期,格式为yyyy-MM-dd:"); String birthdayDateString = sc.next(); //2.使用DateFormat类的parse方法,把字符串的出生日期,解析为Date格式的出生日期 DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date birthdayDate = df.parse(birthdayDateString); //3.把Date格式的出生日期转换成毫秒值 long birdayDateTime = birthdayDate.getTime(); //4.获取当前日期,转换成毫秒值 long todayTime = new Date().getTime(); //5.毫秒值相减 long time = todayTime - birdayDateTime; System.out.println("你活了"+time/1000/60/60/24+"天"); }}Calendar类及其方法
import java.util.Calendar;import java.util.Date;/* * Calendar类的常用成员方法 * public int get(int field):返回给定日历字段的值 * public void set(int field,int value):将给定的日历段设置成给定值 * public abstract void add(int field, int amount): 根据日历规则,为给定的日历字段添加或删去指定的时间量 * public Date getTime(): 返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象 * 成员方法的参数: * int field :日历类的字段,可以使用Calendar类的静态成员变量获取 即Calendar.静态成员变量名 * public static final int YEAR=1; 年 * public static final int MONTH=2; 月 * public static final int DATE=5; 月中的某一天 * public static final int DAY_OF_MONTH=5; 月中的某一天 * public static final int HOUR=10; 时 * public static final int MINUTE=12; 分 * public static final int SECOND=13; 秒 * * */public class Demo02Calendar { public static void main(String[] args) { demo03(); } /* * public Date getTime(): 返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象 * 把日历对象,转换为日期对象 * */ private static void demo04() { //使用getInstance()获取Calendar的子类对象 Calendar c = Calendar.getInstance(); Date time = c.getTime(); System.out.println(time); } /* * public abstract void add(int field, int amount): 根据日历规则,为给定的日历字段添加或删去指定的时间量 把指定的字段的值增加\减少指定的值 * 参数: * int field:传递指定的日历字段(YEAR、MONTH...) * int amount:增加\减少指定的值 * 正数:增加 * 负数:减少 * */ private static void demo03() { //使用getInstance()获取Calendar的子类对象 Calendar c = Calendar.getInstance(); //把年增加两年 c.add(Calendar.YEAR, 2); //把天减少三天 c.add(Calendar.DATE, -3); int year = c.get(Calendar.YEAR); System.out.println(year); int date = c.get(Calendar.DATE); System.out.println(date); } /* * public void set(int field,int value):将给定的日历段设置成给定值 参数: * int field:传递指定的日历字段(YEAR、MONTH...) * int value:给指定字段设置的值 * */ private static void demo02() { //使用getInstance()获取Calendar的子类对象 Calendar c = Calendar.getInstance(); //设置年为9999年 c.set(Calendar.YEAR, 9999); //同时设置年月日,可以使用set的重载方法 c.set(888, 8, 8); int year = c.get(Calendar.YEAR); System.out.println(year); int month = c.get(Calendar.MONTH); System.out.println(month); int date = c.get(Calendar.DATE); System.out.println(date); } /* * * public int get(int field):返回给定日历字段的值 参数:传递指定的日历字段(YEAR、MONTH...) 返回值:日历字段代表具体的值 * */ private static void demo01() { Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); System.out.println(year); int month = c.get(Calendar.MONTH);//西方的月份0-11 System.out.println(month); }}System类及其方法
import java.util.Arrays;/* * java.lang.System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用的方法有: * public static long currentTimeMillis():返回以毫秒为单位的当前时间 * public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length):将数组中指定的数据拷贝到另一个数组中 * */public class Demo01System { public static void main(String[] args) { demo02(); } /* * public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length):将数组中指定的数据拷贝到另一个数组中 *参数: src - 源数组。 srcPos - 源数组中的起始位置(起始索引)。 dest - 目标数组。 destPos - 目标数据中的起始位置。 length - 要复制的数组元素的数量。 练习: * 将src数组中的前3个元素,复制到dest数组的前三个位置上 * 复制元素前: * src数组元素[1,2,3,4,5],dest数组元素[6,7,8,9,10] * 复制元素后: * src数组元素[1,2,3,4,5],dest数组元素[1,2,3,9,10] * * */ private static void demo02() { int[] src = {1, 2, 3, 4, 5}; int[] dest = {6, 7, 8, 9, 10}; System.out.println("dest复制前:" + Arrays.toString(dest)); //使用System类中的arraycopy方法把源数组的前三个元素复制到目标数组的前三个位置上 System.arraycopy(src, 0, dest, 0, 3); System.out.println("dest复制后:" + Arrays.toString(dest)); } /* public static long currentTimeMillis():返回以毫秒为单位的当前时间 用来测试程序的效率 验证for循环打印1-9999所需要的的时间(毫秒) * */ private static void demo01() { //起始时间 long s = System.currentTimeMillis(); for (int i = 1; i System.out.println(i); } //结束时间 long e = System.currentTimeMillis(); System.out.println("for循环打印1-9999所需要的的时间为:" + (e - s) + "毫秒"); }} public static void main(String[] args) { //空参数构造方法 StringBuilder bu1 = new StringBuilder(); //bu1.append("abc"); System.out.println("bu1:" + bu1); //带参数(字符串)构造方法 StringBuilder bu2 = new StringBuilder("abc"); System.out.println("bu2:" + bu2); }}/* * StringBuilder的常用方法: * public StringBuilder append(...)添加任意数据类型的字符串形式,并返回对象自身 * */public class Demo02StringBuilder { public static void main(String[] args) { //创建StringBuilder对象 StringBuilder bu = new StringBuilder("abc"); //append返回的是this,调用方法的对象bu,this==bu StringBuilder bu1 = bu.append("def"); //把bu的地址赋值给了bu1 System.out.println(bu);//abcdef System.out.println(bu1);//abcdef System.out.println(bu1 == bu);//比较的是地址 true //使用append无需接收返回值 //链式编程:返回值是一个对象,可以继续调用方法 bu.append("ghi").append("jkl").append("jkl"); System.out.println(bu); }}ulliStringBuilder和String可以互换pre /* * StringBuilder和String可以互换 * String->StringBuilder:可以使用StringBuilder的构造方法 * StringBuilder(String str)构造一个字符串生成器,并初始化为指定的字符串内容 * StringBuilder->String:可以使用StringBuilder的toString方法 * public String toString();将当前StringBuilder对象转换为String对象 * */public class Demo03StringBuilder { public static void main(String[] args) { //String->StringBuilder String str = "abc"; System.out.println("str:"+str); StringBuilder str1 = new StringBuilder(str); //往StringBuilder中添加数据 str1.append("def"); System.out.println("str1:"+str1); //StringBuilder->String String str2 = str1.toString(); System.out.println("str2:"+str2); }}包装类Integer及其方法
/*装箱:把基本类型的数据,包装到包装类中(基本数据类型->包装类) 构造方法: Integer(int value)构造一个新分配的Integer对象,它表示指定的int值 Integer(String s)构造一个新分配的String对象,它表示String参数所指示的int值 传递的字符串,必须是基本类型的字符串,否则会抛出异常 "100"正确 "a"抛出异常 静态方法: static Integer valueOf(int i)返回一个int值的Integer实例 static Integer valueOf(String s)返回保存指定的String的值的Integer对象拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据) 成员方法: int intValue()以int类型返回该Integer的值 * */public class Demo01Integer { public static void main(String[] args) { //装箱:把基本类型的数据,包装到包装类中(基本数据类型->包装类) //构造方法 Integer in1 = new Integer(1);//方法上有横线,说明方法过时了 System.out.println(in1);// 1 -- 重写了toString方法(对象输出的不是地址) Integer in2 = new Integer("10");//传递的字符串,必须是基本类型的字符串,否则会抛出异常 "100"正确 "a"抛出异常 System.out.println(in2); //静态方法 Integer in3 = Integer.valueOf(1); System.out.println(in3); Integer in4 = Integer.valueOf("10"); System.out.println(in4); //拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据) //成员方法 int i = in4.intValue(); System.out.println(i); }}- 自动装箱和自动拆箱:基本类型的数据和包装类之间可以自动的相互转换
import java.util.ArrayList;/*自动装箱和自动拆箱:基本类型的数据和包装类之间可以自动的相互转换 * */public class Demo02Integer { public static void main(String[] args) { /*自动装箱:直接把int类型的整数赋值给包装类 Integer in = 1;就相当于Integer in = new Integer(1); * */ Integer in = 1; /*自动拆箱:in是包装类,无法直接参与运算,可以自动转换为基本数据类型,再进行计算 in + 2;就相当于 in.intValue()+2=3 in=in.intValue()+2又是一个自动装箱 * */ in = in + 2; ArrayList list = new ArrayList(); /*ArrayList集合无法直接存储整数,可以存储Integer包装类*/ list.add(1);//-->自动装箱 list.add(new Integer(1)); int a = list.get(0);//-->自动拆箱 list.get(0).intValue; System.out.println(list); }}基本数据类型 包装类byte Byte boolean Boolean short Short char Character int Integer long Long float Float double Double
- 包装类基本类型与字符串之间转换
/* * 基本类型与字符串之间的转换 * 基本类型->字符串(String) * 1.基本类型的值+"" 最简单的方法(工作中常用) * 2.包装类的静态方法toString(int i)不是Object类的toString() 重载 * static String toString(int i)返回一个表示指定整数的String对象 * 3.String类的静态方法ValueOf(参数) * static String valueOf(int i)返回int参数的字符串表示形式 * 字符串(String)->基本类型 * 使用包装类的静态方法parseXXX("字符串"); * Integer类:static int parseInt(String s) * Double类:static double parseDouble(String s) * */public class Demo03Integer { public static void main(String[] args) { //基本类型->字符串(String) int i1 = 100; String s1 = i1 + ""; System.out.println(i1 + 200);//100200 String s2 = Integer.toString(100);//返回一个表示指定整数的String对象 System.out.println(s2 + 200);//100200 String s3 = String.valueOf(100);//返回int参数的字符串表示形式 System.out.println(s3 + 200);//100200 //字符串(String)->基本类型 int i2 = Integer.parseInt(s1); System.out.println(i2 + 10); /*int a=Integer.parseInt("a"); System.out.println(a);*/ double a = Double.parseDouble("1.1"); System.out.println(a); }}Collection接口及其方法
import java.util.ArrayList;import java.util.Collection;/** java.util.Collection接口* 所有单列集合最顶层的接口,里边定义了所有单列集合共性的方法* 任意的单列集合都可以使用Collection接口中的方法** 共性的方法: boolean add(E e)确保此 collection 包含指定的元素(可选操作)。 boolean remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 void clear()移除此 collection 中的所有元素(可选操作)。 boolean contains(Object o)如果此 collection 包含指定的元素,则返回 true。 boolean isEmpty()如果此 collection 不包含元素,则返回 true。 int size()返回此 collection 中的元素数。 Object[] toArray()返回包含此 collection 中所有元素的数组。* */class Demo01Collection { public static void main(String[] args) { //创建集合对象,使用多态 Collection coll = new ArrayList(); System.out.println(coll);//重写了toString方法 /* boolean add(E e)确保此 collection 包含指定的元素(可选操作)。 * 返回值是一个boolean值,一般我都返回true,所以不用接收*/ coll.add("陈浩"); coll.add("猪比"); coll.add("狗江"); coll.add("骚彪"); System.out.println(coll); /* boolean remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 返回值是一个boolean值,集合中存在元素,删除元素,返回true 集合中不存在元素,删除失败,返回false * */ boolean b1 = coll.remove("陈浩"); System.out.println(b1); boolean b2 = coll.remove("shab"); System.out.println(b2); /*boolean contains(Object o)如果此 collection 包含指定的元素,则返回 true。 * 包含返回true * 不包含返回false*/ boolean b3 = coll.contains("陈浩"); System.out.println(b3); boolean b4 = coll.contains("陈"); System.out.println(b4); /*boolean isEmpty()如果此 collection 不包含元素,则返回 true。 * 集合为空返回true,集合不为空返回false*/ boolean b5 = coll.isEmpty(); System.out.println(b5); /*int size()返回此 collection 中的元素数。 * 返回集合中元素个数*/ int size = coll.size(); System.out.println(size); /*Object[] toArray()返回包含此 collection 中所有元素的数组。 * 把集合中的元素存储到数组中*/ Object[] obj = coll.toArray(); for (int i = 0; i迭代器Iterator
import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/* * * java.util.Iterator接口:迭代器(对集合进行遍历) * 有两个常用方法: * boolean hasNext()如果仍有元素可以迭代,则返回true,没有返回false * 判断集合中还有没有下一个元素,如果有返回true,没有返回false * E next()返回迭代的下一个元素 * 取出集合下一个元素 * Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象 * 获取实现类的方式比较特殊,Collection接口有一个方法叫iterator(),这个方法返回的就是迭代器的实现类对象 * Iterator iterator()返回在此Collection的元素上进行迭代的迭代器 * * 迭代器的使用步骤(重点): * 1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态) * 2.使用Iterator接口中的方法hasNext()判断还有没有下一个元素 * 3.使用Iterator接口中的方法next()取出下一个元素 * */public class Demo01Iterator { public static void main(String[] args) { Collection coll = new ArrayList(); coll.add("陈浩"); coll.add("陈bb"); coll.add("陈cc"); coll.add("陈dd"); coll.add("陈ee"); /*1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态) * 注意: * Iterator也是有泛型的,迭代器的泛型跟着集合走 * */ //接口 实现类对象 Iterator it = coll.iterator();//多态 /*2.使用Iterator接口中的方法hasNext()判断还有没有下一个元素*/ while (it.hasNext()) { //3.使用Iterator接口中的方法next()取出下一个元素 String str = it.next(); System.out.println(str); } System.out.println("================"); for (Iterator it2 = coll.iterator(); it2.hasNext();/*每次自动向后移一位*/) { String str2 = it2.next(); System.out.println(str2); } }}增强for循环
import java.util.ArrayList;import java.util.Collection;/* * 增强for循环:底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写 * 是JDK1.5之后出现的新特性 * Collectionextends Iterable:所有单列集合都可以使用增强for循环 * public interface Iterable实现这个类接口允许对象成为"foreach"语句的目标 * * 增强for循环:用来遍历集合和数组 * * 格式: * for(集合/数组的数据类型 变量名:集合名/数组名){ * sout(变量名); * } * */public class Demo03Foreach { public static void main(String[] args) { demo01(); System.out.println("======================"); demo02(); } //使用增强for循环遍历集合 private static void demo02() { /*Collectionextends Iterable:所有单列集合都可以使用增强for循环 * public interface Iterable实现这个类接口允许对象成为"foreach"语句的目标*/ // ArrayList list = new ArrayList(); Collection list = new ArrayList(); list.add("陈浩"); list.add("陈aa"); list.add("陈bb"); list.add("陈cc"); list.add("陈dd"); for (String s : list) { System.out.println(s); } } //使用增强for循环遍历数组 private static void demo01() { int[] arr = {1, 2, 3, 4, 6}; for (int i : arr) { System.out.println(i); } }}泛型
- 就是类似ArrayList集合的
import java.util.ArrayList;import java.util.Iterator;public class Demo01Generic { public static void main(String[] args) { show01(); } /* * 创建集合对象时,不使用泛型 * 好处: * 1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型 * 2.把运行期异常(代码运行之后的异常),提升到了编译器(编译时报错) * 弊端: * 泛型是什么类型,只能存储什么类型的数据 * */ private static void show02() { ArrayList list = new ArrayList(); list.add("abc");// list.add(1);//java: 不兼容的类型: int无法转换为java.lang.String //使用迭代器遍历list集合 Iterator it = list.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s+"->"+s.length()); } } /* * 创建集合对象时,不使用泛型 * 好处: * 集合不使用泛型,默认的是Object类型,可以存储任何形式的数据 * 弊端: * 不安全,会引发异常 * */ private static void show01() { ArrayList list = new ArrayList(); list.add("abc"); list.add(1); list.add(8.8); //使用迭代器遍历list集合 //获取迭代器 Iterator it = list.iterator(); while (it.hasNext()) { //取出元素也是Object类型 Object obj = it.next(); System.out.println(obj); //想要String类特有的方法,length获取字符串长度;不能使用 多态Object obj="abc"; //需要向下转型 String s = (String) obj; //会抛出ClassCastException类型转换异常,不能把Integer类型转换为String类型 System.out.println(s.length()); } }}泛型类
import java.util.ArrayList;/* * 定义一个含有泛型的类(可以叫集合),模拟ArrayList集合 * 泛型是一个未知的数据类型,当我们不确定是什么数据类型的时候,可以使用泛型 * 泛型可以接收任意数据类型,可以使用Integer、String,Student... * 创建对象的时候确定泛型的数据类型 * */public class GenericClass { private E name; public E getName() { return name; } public void setName(E name) { this.name = name; }}public class Demo02GenericClass { public static void main(String[] args) { //不写泛型默认为Object类型 GenericClass gc = new GenericClass(); gc.setName("sb"); System.out.println(gc.getName()); //创建GenericClass对象,泛型使用Integer类型 GenericClass gc2 = new GenericClass(); gc2.setName(1); System.out.println(gc2.getName()); }}- 定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
/* * 定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间 * * 格式: * 修饰符 返回值类型 方法名(参数列表(使用泛型)){ * 方法体; * } * * 含有泛型的方法,在调用方法的时候确定泛型的数据类型 * 传递什么类型的参数,泛型就是什么类型 * */public class GenericMethod { //定义一个含有泛型的方法 public void method01(M m) { System.out.println(m); } //定义一个含有泛型的静态方法 public static void method02(S s){ System.out.println(s); }}/* * 测试含有泛型的方法 * */public class Demo03GenericMethod { public static void main(String[] args) { //创建GenericMethod对象 GenericMethod gc = new GenericMethod(); /* * 调用含有泛型的方法method01 * 传递什么类型,泛型就是什么类型 * */ gc.method01(11); gc.method01("sb"); gc.method01(1.1); gc.method01(true); System.out.println("==============="); GenericMethod.method02("静态方法"); GenericMethod.method02(1.1); }}泛型接口
/* * 定义含有泛型的接口 * */public interface GenericInterface { public abstract void method(I i);}- 含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型
/* * 含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型 * public interface Iterator { * E next(); * } * Scanner类实现了Iterator接口,并在指定接口的泛型为String,使用重写的next方法的泛型默认为String * public final class Scanner implements Iterator{ * public String next(); * } * */public class GenericInterfaceImpl1 implements GenericInterface { @Override public void method(String s) { System.out.println(s); }}- 含有泛型接口的第二种使用方式:接口使用什么类型,实现类就使用什么类型,类跟着接口走
/* * 含有泛型接口的第二种使用方式:接口使用什么类型,实现类就使用什么类型,类跟着接口走 * 就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型 * public interface List{ * boolean add(E e); * E get(int index); * } * public class ArrayList implements list{ * public boolean add(E e){} * public E get(int index){} * } * */public class GenericInterfaceImpl2 implements GenericInterface { @Override public void method(I i) { System.out.println(i); }}测试
public class Demo04GenericInterface { public static void main(String[] args) { //创建GenericImplement1对象 GenericInterface gi = new GenericInterfaceImpl1();//多态 gi.method("abc"); //创建GenericImplement2对象 GenericInterfaceImpl2 gi2 = new GenericInterfaceImpl2(); gi2.method("def"); System.out.println("===================="); GenericInterfaceImpl2 gi3 = new GenericInterfaceImpl2(); gi3.method(2.2); System.out.println("===================="); GenericInterfaceImpl2 gi4 = new GenericInterfaceImpl2(); gi4.method(5); }}通配符 ? 的用法
import java.util.ArrayList;import java.util.Iterator;/* * 泛型的通配符: * ?:代表任意的数据类型 * 使用方式: * 不能创建对象使用 * 只能作为方法的参数使用 * */public class Demo05Generic { public static void main(String[] args) { ArrayList list01 = new ArrayList(); list01.add(1); list01.add(2); ArrayList list02 = new ArrayList(); list02.add("abc"); list02.add("def"); printArray(list01); printArray(list02); } /* * 定义一个方法,能遍历所有类型的ArrayList集合 * 这时候我们不知道ArrayList集合使用什么数据类型类型,可以使用泛型的通配符?来接收数据类型 * 注意: * 泛型是没有继承概念的 * */ public static void printArray(ArrayList list) { //使用迭代器遍历集合 Iterator it = list.iterator(); while (it.hasNext()) { //it.next()方法,取出的元素是Object,可以接收任意的数据类型 Object obj = it.next(); System.out.println(obj); } }}泛型的上限限定和泛型的下限限定
- 泛型的上限限定:? extends E 代表使用的泛型只能是E的子类或者本身
- 泛型的下限限定:? super E 代表使用的泛型只能是E的父类或者本身
import java.util.ArrayList;import java.util.Collection;/* * 泛型的上限限定:? extends E 代表使用的泛型只能是E的子类或者本身 * 泛型的下限限定:? super E 代表使用的泛型只能是E的父类或者本身 * */public class Demo06Generic { public static void main(String[] args) { ArrayList list1 = new ArrayList(); ArrayList list2 = new ArrayList(); ArrayList list3 = new ArrayList(); ArrayList list4 = new ArrayList(); getElement1(list1);// getElement1(list2);//报错 getElement1(list3);// getElement1(list4);//报错// getElement2(list1);//报错// getElement2(list2);//报错 getElement2(list3); getElement2(list4); } /* * 类与类之间的继承关系 * Integer extends Number extends Object * String extends Object * */ //泛型的上限:此时的泛型必须是Number类型的子类或Number类型 public static void getElement1(ArrayList list ) 使用随机默认源对指定列表进行打印 * */ Collections.shuffle(poker);// System.out.println(poker); //发牌 //先创建四个集合 //3个玩家集合 ArrayList play01 = new ArrayList(); ArrayList play02 = new ArrayList(); ArrayList play03 = new ArrayList(); //一个底牌集合 ArrayList dipai = new ArrayList(); for (int i = 0; i =51时发牌给底牌 //从索引%3给三个玩家轮流发牌 //注意,先判断i>=52,否则牌就发没了 String p = poker.get(i);//获取牌 if (i >= 51) { //底牌 dipai.add(p); } else if (i % 3 == 0) { //给玩家1发牌 play01.add(p); } else if (i % 3 == 1) { //给玩家2发牌 play02.add(p); } else if (i % 3 == 2) { //给玩家3发牌 play03.add(p); } } //看牌 System.out.println("周星驰"+play01); System.out.println("刘德华"+play02); System.out.println("周润发"+play03); System.out.println("底牌"+dipai); }}List集合及其方法
/* * java.util.List接口extends Collection接口 * List接口的特点: * 1.有序的集合,存储元素和取出元素顺序一致 * 2.有索引,包含了一些有索引的方法 * 3.允许存储重复的元素 * * List接口中带有索引的方法(特有) * public void add(int index,E element):将指定的元素,添加到集合中的指定位置上 * public E get(int index):返回集合中指定位置的元素 * public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素 * public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回值是更新前的元素 * 注意: * 操作索引的时候,一定要防止索引越界异常 * IndexOutOfBoundsException:索引越界异常,集合会报 * ArrayIndexOutOfBoundsException:数组索引越界异常 * StringIndexOutOfBoundsException:字符串索引越界异常 * */public class Demo01List { public static void main(String[] args) { //创建一个List集合对象,多态 List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); System.out.println(list);//打印的不是地址,重写了toString方法 /* public void add(int index,E element):将指定的元素,添加到集合中的指定位置上 */ list.add(4, "e"); System.out.println(list); /* * public E get(int index):返回集合中指定位置的元素 * */ for (String s : list) { System.out.println(s); } /* * public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素 * */ String removeE = list.remove(3); System.out.println("被移除的元素:" + removeE); System.out.println(list); /* * public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回值是更新前的元素 * */ String setE = list.set(3, "D"); System.out.println("被替换的是" + setE); System.out.println(list);// String r = list.get(5);//IndexOutOfBoundsException// System.out.println(r); }}LinkedList集合及其方法
import java.util.LinkedList;/* * java.util.LinkedList集合 implements List集合 * linkedList集合的特点: * 1.底层是一个链表结构,查询慢,增删快 * 2.里面包含了大量首尾元素的方法 * 注意:使用linkedList集合特有的方法,不能使用多态 * * public void addFirst(E e):将指定元素插入此列表的开头 * public void addLast(E e):将指定元素添加到此列表的末尾 * public void push(E e):将元素推入此列表表示的堆栈 * * public E getFirst():返回此列表的第一个元素 * public E getLast():返回此列表的最后一个元素 * * public E removeFirst():移除并返回此列表第一个元素 * public E removeLast():移除并返回此列表最后一个元素 * public E pop():从此列表所表示的堆栈弹出第一个元素 * * public boolean isEmpty():如果列表不包含元素,则返回true * * */public class Demo01LinkedList { public static void main(String[] args) { show02(); } /* * public E removeFirst():移除并返回此列表第一个元素 * public E removeLast():移除并返回此列表最后一个元素 * public E pop():从此列表所表示的堆栈弹出第一个元素 相当于removeFirst() * */ private static void show03() { //创建LinkedList集合对象 LinkedList linked = new LinkedList(); //往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c"); //public E removeFirst():移除并返回此列表第一个元素 //String first = linked.removeFirst(); String first = linked.pop(); System.out.println("被移除的第一个元素是:" + first); System.out.println(linked); //public E removeLast():移除并返回此列表最后一个元素 String last = linked.removeLast(); System.out.println("被移除的最后一个元素是:" + last); System.out.println(linked); } /* * public E getFirst():返回此列表的第一个元素 * public E getLast():返回此列表的最后一个元素 * */ private static void show02() { //创建LinkedList集合对象 LinkedList linked = new LinkedList(); //往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c");// linked.clear(); if (!linked.isEmpty()) { //public E getFirst():返回此列表的第一个元素 String first = linked.getFirst(); System.out.println(first); System.out.println(linked); //public E getLast():返回此列表的最后一个元素 String last = linked.getLast(); System.out.println(last); System.out.println(linked); } } /* * public void addFirst(E e):将指定元素插入此列表的开头 * public void addLast(E e):将指定元素添加到此列表的末尾 * public void push(E e):将元素推入此列表表示的堆栈 * */ public static void show01() { //创建LinkedList集合对象 LinkedList linked = new LinkedList(); //往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c"); System.out.println(linked); //public void addFirst(E e):将指定元素插入此列表的开头 //linked.addFirst("www"); linked.push("www"); System.out.println(linked); //public void addLast(E e):将指定元素添加到此列表的末尾 等效于add(E e) linked.addLast("com"); System.out.println(linked); }}Set集合及其方法
HashSet集合及其方法
/* * java.util.Set接口 extends Collection接口 * Set接口的特点: * 1.不允许存储重复元素 * 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 * * java.util.HashSet接口 implements Set接口 * HashSet接口特点: * 1.不允许存储重复元素 * 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 * 3.是一个无序的集合,存储元素和取出元素顺序可能不一致 * 4.底层是一个哈希表(查询速的非常快) * */public class Demo02Set { public static void main(String[] args) { Set hasSet = new HashSet(); //使用add方法往集合中添加元素 hasSet.add(1); hasSet.add(2); hasSet.add(3); hasSet.add(1); //使用迭代器遍历hasSet集合 Iterator it = hasSet.iterator(); while (it.hasNext()) { Integer i = it.next(); System.out.println(i); } System.out.println("====================="); //使用增强for循环遍历hasSet集合 for (Integer i : hasSet) { System.out.println(i); } }}哈希值
/* * 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来的得到的地址,不是数据实际存储的物理地址) * 在Object类有一个方法,可以获取对象的哈希值 * int hashCode() 返回该对象的哈希码值 * hashCode方法的源码 * public native int hashCode(); * native:代表该方法调用的是本地操作系统的方法 * */public class Demo03HashCode { public static void main(String[] args) { //Person类继承了Object类,所以可以使用Object类的hashCode方法 Person p1 = new Person(); int h1 = p1.hashCode(); System.out.println(h1); Person p2 = new Person(); int h2 = p2.hashCode(); System.out.println(h2); /* * toString方法的源码: * return getClass().getName()+"@"+Integer.toHexString(hashCode()); * */ System.out.println(p1); System.out.println(p2); /* * String 类的哈希值 * String类重写了Object类的hashCode方法 * */ String s1=new String("abc"); String s2=new String("abc"); int i1 = s1.hashCode(); int i2 = s2.hashCode(); System.out.println(i1); System.out.println(i2); System.out.println("重地".hashCode());//1179395 System.out.println("通话".hashCode());//1179395 }}- Set集合不允许存储重复元素的原理
/* * Set集合不允许存储重复元素的原理 * Set集合在调用add方法时,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复 * */public class Demo04HashSetSaveString { public static void main(String[] args) { //创建hashSet集合对象 HashSet set = new HashSet(); String s1 = new String("abc"); String s2 = new String("abc"); set.add(s1); /* *add方法会调用s1的hashCode方法,计算字符串"abc"的哈希值,是96354, * 在集合中找到没有96354这个哈希值的元素,发现没有 * 就会把s1存储集合中 * */ set.add(s2); /* * add方法会调用s1的hashCode方法,计算字符串"abc"的哈希值,是96354, * 在集合中找到有96354这个哈希值的元素,发现有(哈希冲突) * s2会调用equals方法和哈希值相同的元素进行比较 s2.equals(s1),返回true * 两个元素的哈希值相同,equals方法返回true,认定两个元素相同 * 就不会把s2存储到集合中 * */ set.add("重地"); /* * add方法会调用s1的hashCode方法,计算字符串"重地"的哈希值,是1179395, * 在集合中找到没有1179395这个哈希值的元素,发现没有 * 就会把"重地"存储集合中 * */ set.add("通话"); /* add方法会调用s1的hashCode方法,计算字符串"通话"的哈希值,是1179395, * 在集合中找到有1179395这个哈希值的元素,发现有(哈希冲突) * "通话"会调用equals方法和哈希值相同的元素进行比较 "通话".equals("重地"),返回false (String对比) * 两个元素的哈希值相同,equals方法返回false,认定两个元素不相 * 就会把"通话"存储到集合中 * */ set.add("abc"); System.out.println(set); }}小测试
import java.util.Objects;public class People { private String name; private int age; public String getName() { return name; } @Override public String toString() { return "People{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; People people = (People) o; return age == people.age && Objects.equals(name, people.name); } @Override public int hashCode() { return Objects.hash(name, age); } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public People(String name, int age) { this.name = name; this.age = age; } public People() { }}import java.util.HashSet;/* * HashSet自定义类型元素 * * Set集合报错元素唯一: * 存储的元素(String,Integer.. Student),必须重写hashCode方法和equals方法 * * 要求: * 同名同年龄,视为同一个人,只能存储一次 * */public class Demo05HashSetSavePeople { public static void main(String[] args) { //创建HashSet集合存储People HashSet set = new HashSet(); People p1 = new People("陈浩", 11); People p2 = new People("陈浩", 11); People p3 = new People("陈浩", 12); System.out.println(p1.hashCode()); System.out.println(p2.hashCode()); System.out.println(p1 == p2);//比较的是地址 System.out.println(p1.equals(p2)); set.add(p1); set.add(p2); set.add(p3); System.out.println(set); }}LinkedHashSet集合及其方法
import java.util.HashSet;import java.util.LinkedHashSet;/* * java.util.LinkedHashSet集合 extends HashSet集合 * LinkedHashSet集合特点 * 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素存储顺序),保证元素有序 * */public class Demo06LinkedHashSet { public static void main(String[] args) { HashSetset=new HashSet(); set.add("www"); set.add("abc"); set.add("abc"); set.add("xpzt"); set.add("com"); System.out.println(set);//无序,不允许重复 LinkedHashSet linked=new LinkedHashSet(); linked.add("www"); linked.add("abc"); linked.add("abc"); linked.add("xpzt"); linked.add("com"); System.out.println(linked);//有序,不允许重复 }}可变参数
-
当方法的参数列表类型已经确定,但是参数的个数不确定,就可以使用可变参数
-
可变参数的注意事项:
- 一个方法的参数列表,只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
-
使用格式:
-
修饰符 返回值类型 方法名(数据类型…变量名){}
//使用格式public static void method(String str,Object...obj){}/* * 可变参数:是JDK1.5之后出现的新特性 * 使用前提: * 当方法的参数列表类型已经确定,但是参数的个数不确定,就可以使用可变参数 * 使用格式: * 修饰符 返回值类型 方法名(数据类型...变量名){} * 可变参数的原理: * 可变参数的底层是一个数组,根据传递的参数不同,会创建不同长度的数组,来存储这些参数 * 传递的参数个数,可以是0个(不传递)或者1,2..多个 * * */public class DemoVarArgs { public static void main(String[] args) {// int i = add(); int i = add(10, 20, 30, 40, 50, 60, 70, 80, 90, 100); System.out.println(i); method("abc",3.4,3,1,3,4,5,6,7,4); } /* * 可变参数的注意事项: * 1.一个方法的参数列表,只能有一个可变参数 * 2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾 * */// public static void method(String s,double b,int i,int...arr){// } /* * 可变参数的特殊写法(终级写法) * */ public static void method(String str,Object...obj){ } /* * 定义计算(0-n)整数和的方法 * 已知:计算整数的和,数据类型已经确定int * 但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数 * add();就会创建一个长度为0的数组,new int[0] * add(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);就会创建一个长度为10的数组,new int[]{10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; * */ public static int add(int... arr) {// System.out.println(arr);// System.out.println(arr.length); //定义一个初始化的变量,记录累加求和 int sum = 0; //遍历数组 for (int i : arr) { sum += i; } return sum; }}Collection集合工具类及其方法
import java.util.ArrayList;import java.util.Collection;import java.util.Collections;/* * java.util.Collections是集合工具类,用来对集合进行操作,部分方法如下: * public static boolean addAll(Collection c,T... element):往集合中添加一些元素 * public static shuffle(List list)打乱顺序:打乱集合顺序 * */public class Demo01Collections { public static void main(String[] args) { ArrayList list=new ArrayList(); list.add("a"); list.add("b"); list.add("d"); list.add("c"); System.out.println(list); /* * public static boolean addAll(Collection c,T... element):往集合中添加一些元素 * */ Collections.addAll(list,"3","4","2"); System.out.println(list); /* * public static shuffle(List list)打乱顺序:打乱集合顺序 * */ Collections.shuffle(list); System.out.println(list); }}Comparable接口
-
自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较的CompareTo方法
-
Comparable接口的排序规则:定义比较的规则
- 自己(this)-参数:升序
- 参数-自己(this):降序
-
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较的CompareTo方法
-
Comparator:相当于第三方的裁判,比较两个
public class Person implements Comparable { private String name; private int 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 "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Person(String name, int age) { this.name = name; this.age = age; } public Person() { } //重写排序规则 @Override public int compareTo(Person o) {// return 0;//认为元素都是相同的 //自定义比较的规则,比较两个人的年龄(this,参数Person)// return this.getAge()-o.getAge();//升序 return o.getAge() - this.getAge();//降序 }}import java.util.ArrayList;import java.util.Collections;/* * java.util.Collections是集合工具类,用来对集合进行操作,部分方法如下: * public static void sort(List list):将集合中的元素按照默认规则排序 * * 注意: * sort(List list)使用前提 * 被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则 * Comparable接口的排序规则: * 自己(this)-参数:升序 * */public class Demo02Sort { public static void main(String[] args) { ArrayList list01 = new ArrayList(); list01.add(1); list01.add(3); list01.add(2); System.out.println(list01); /* * public static void sort(list list):将集合中的元素按照默认规则排序 * */ Collections.sort(list01); System.out.println(list01); ArrayList list02 = new ArrayList(); list02.add("a"); list02.add("c"); list02.add("b"); System.out.println(list02); Collections.sort(list02); System.out.println(list02); ArrayList list03 = new ArrayList(); list03.add(new Person("陈浩", 11)); list03.add(new Person("cc", 15)); list03.add(new Person("陈bb", 4)); System.out.println(list03); Collections.sort(list03); System.out.println(list03); }}小测试
/* * java.util.Collections是集合工具类,用来对集合进行操作,部分方法如下: * public static void sort (List list,Comparator
-
-
-
- Set集合不允许存储重复元素的原理
- 含有泛型接口的第二种使用方式:接口使用什么类型,实现类就使用什么类型,类跟着接口走
- 含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型
- 定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
- 就是类似ArrayList集合的
- 包装类基本类型与字符串之间转换
- 自动装箱和自动拆箱:基本类型的数据和包装类之间可以自动的相互转换
- 看一个类是否重写了toString,直接打印这个类的对象即可,如果没有重写toString方法,那么打印的是对象的地址值
- 通过外部类名称.内部类名称 对象名 = new 外部类名称().new内部类名称() 调用内部类方法
- 内部类和外部类成员变量出现重名,则引用外部类成员变量格式:外部类.this.外部成员变量名
- 向下转型一定要进行instanceof判断,否则可能发生类转换异常
-
- 在类中,被static修饰的方法称作静态方法。同静态变量一样,如果该静态方法的访问权限高于private,则该静态方法可通过“类名.方法名/接口名.方法名”直接调用,而不需要创建对象调用
- 接口是默认使用抽象方法的,使用其他类实现接口类
- 子类可以用super调用父类的成员方法或成员变量
- 子类可以继承父类的成员方法及成员变量并在父类的基础上加以延伸
- this只能调用本类的成员方法或成员变量