1
class helloworld {
public static void main (String[] args) {
System.out.println("helloworld!");
}
}
2 命名规则
标识符起名:不能以数字开头,不能是java的关键字,区分大小写
标识符组成规则:英文大小写,数字,$和_
包名要求全部小写,一般是公司的域名倒着写
例如:com.heima.包的作用
类或接口
如果是一个单词,要求首字母大写,如果是多个单词要求每个单词首字母大写(驼峰命名)
DemoStudent
方法和变量
如果是一个单词,每个字母都小写,如果是多个单词,从第二个单词开始首字母大写
getName setName maxValue常量
如果是一个单词,所有字母大写,如果是多个单词也是所有字母大写,但是用_分开
MAX
MAX_VALUE
3 进制
- 1byte=8bit 1m=1024k 1g=1024m 1t=1024g
- 0b110 表示二进制的110
- 0110 表示八进制110
- 0x110 表示十六进制的22
- 十进制转换任意进制:除积倒取余数
- 二进制转八进制:每3位划成一组
- 二进制转十六进制:每4位划成一组
- 8421码二进制快速转任意进制
4 原码 反码 补码
- 原码
- 最高位是符号位,“0”表示正,“1”表示负
- 反码
- 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
- 补码
- 正数的反码与其原码相同;负数的补码是在其反码的末位加1。
多态
- 多态的前提
- 要有继承或实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
- 多态成员访问特点
- 成员变量:编译看父类,运行看父类
- 成员方法:编译看父类,运行看子类
- 向上转型
- 父类引用指向子类对象就是向上转型
- 向下转型
- 格式:子类型 对象名 = (子类型)父类引用;
- 多态的好处:提高可扩展性
- 多态的弊端:无法调用子类特有的方法
抽象类
- 抽象类和抽象方法必须使用abstract修饰
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类通过子类,采用多态的形式实例化(不能直接实例化)
- 抽象类的子类必须重写抽象类中的所有抽象方法(抽象类的子类本身是个抽象类除外)
- 抽象方法定义:public abstract 返回值类型 方法名();
接口
接口就是一种规范
接口的成员变量默认被public static final修饰,是个常量,可以 接口名.变量名 直接调用。
接口的成员方法默认被 public abstract修饰。
接口没有构造方法。
接口内不能有非抽象方法。
接口和抽象类的区别?
抽象类有局限性,只能继承一次,唯一的继承位一定是留给共性抽取的
接口可以实现任意个,接口可以定义规范
接口不能直接实例化。接口如何实例化呢?
-
参照多态的方式,通过实现类对象实例化,这叫接口多态。
【多态的形式:具体类多态,抽象类多态,接口多态。】
接口的子类
要么重写接口中的所有抽象方法
要么子类也是抽象类
接口和接口关系是继承关系,可以多继承
内部类
内部类可分为两种形式
成员内部类
局部内部类
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
匿名内部类
前提:存在一个类或者接口,可以是具体类也可以是抽象类
本质:是一个继承了该类或者实现了该接口的子类匿名对象
解释: 匿名(匿了实现类的名字) 内部类 (这个类是在main方法内的局部内部类)
-
匿名内部类的格式
格式:new 类名 ( ) { 重写方法 } new 接口名 ( ) { 重写方法 }
举例:
java
new Inter(){
@Override
public void method(){}
} ;
-
匿名内部类直接调用方法
例1
java
interface Inter{
void method();
}class Test{ public static void main(String[] args){ new Inter(){ //这是一个匿名内部类,也是匿名对象 @Override public void method(){ System.out.println("我是匿名内部类"); } }.method(); // 直接调用方法 } }
例2
java
interface Inter{
void method();
}
class Test{
public static void main(String[] args){
Inter i=new Inter(){ //这是一个匿名内部类,不是匿名对象
@Override
public void method(){
System.out.println("我是匿名内部类");
}
};
i.method(); // 调用方法
}
}
常用API
- Math()
- Math类的常用方法
方法名 方法名 | 说明 |
---|---|
public static int abs(int a) | 返回参数的绝对值 |
public static double ceil(double a) | 返回大于或等于参数的最小double值,等于一个整数 |
public static double floor(double a) | 返回小于或等于参数的最大double值,等于一个整数 |
public static int round(float a) | 按照四舍五入返回最接近参数的int |
public static int max(int a,int b) | 返回两个int值中的较大值 |
public static int min(int a,int b) | 返回两个int值中的较小值 |
public static double pow (double a,double b) | 返回a的b次幂的值 |
public static double random() | 返回值为double的正值,[0.0,1.0) |
- System
- System类的常用方法
| 方法名 | 说明 |
| ---------------------------------------- | --------------------------------------------- - |
| public static void exit(int status) | 终止当前运行的 Java 虚拟机,非零表示异常终止 |
| public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
- Object类
- 重写toString方法的方式
- Alt + Insert 选择toString
- 在类的空白区域,右键 -> Generate -> 选择toString
toString方法的作用:
以良好的格式,更方便的展示对象中的属性值重写equals方法的场景
不希望比较对象的地址值,想要结合对象属性进行比较的时候。重写equals方法的方式
alt + insert 选择equals() and hashCode(),IntelliJ Default,一路next,finish即可-
Arrays的常用方法
方法名 说明 public static String toString(int[] a) 返回指定数组的内容的字符串表示形式 public static void sort(int[] a) 按照数字顺序排列指定的数组
基本包装类
- Integer 类
- Integer的构造方法
方法名 | 说明 |
---|---|
public Integer(int value) | 根据 int 值创建 Integer 对象(过时) |
public Integer(String s) | 根据 String 值创建 Integer 对象(过时) |
public static Integer valueOf(int i) | 返回表示指定的 int 值的 Integer 实例 |
public static Integer valueOf(String s) | 返回一个保存指定值的 Integer 对象 String |
int和String类型的相互转换
- int转换为String
- 转换方式
- 方式一:直接在数字后加一个空字符串
- 方式二:通过String类静态方法valueOf()
- String转换为int
- 转换方式
- 方式一:先将字符串数字转成Integer,再调用intValue()方法
Integer i = Integer.valueOf(s);
int x = i.intValue(); -
方式二:通过Integer静态方法parseInt()进行转换
int y = Integer.parseInt(s);
- 方式一:先将字符串数字转成Integer,再调用intValue()方法
- StringBuilder类
- 构造方法
StringBuilder sb = StringBuilder(); - 常用方法
append(String s) :在字符串后连接字符串s
String toString() :返回字符串结果
自动装箱和拆箱
-
自动装箱
把基本数据类型转换为对应的包装类类型
-
自动拆箱
把包装类类型转换为对应的基本数据类型
例子:
Integer i = 100; // 自动装箱
i += 200; // i = i + 200; i + 200 自动拆箱;i = i + 200; 是自动装箱
时间、日期类
Date类
-
构造方法
方法名 说明 public Date() 分配一个 Date对象,并初始化,默认为创建对象时的时间,精确到毫秒 public Date(long date) 分配一个 Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数 -
常用方法
方法名 说明 public long getTime() 获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值 public void setTime(long time) 设置时间,给的是毫秒值 【getTime(long time)和System.currentTimeMillis()类似。】
SimpleDateFormat类
-
SimpleDateFormat类构造方法
方法名 说明 public SimpleDateFormat() 构造一个SimpleDateFormat,使用默认模式和日期格式 public SimpleDateFormat(String pattern) 构造一个SimpleDateFormat使用给定的模式和默认的日期格式 -
SimpleDateFormat类的常用方法
- 格式化(从Date到String)
- public final String format(Date date):将日期格式化成日期/时间字符串
- 解析(从String到Date)
- public Date parse(String source):从给定字符串的开始解析文本以生成日期
- 格式化(从Date到String)
-
示例代码
public class SimpleDateFormatDemo { public static void main(String[] args) throws ParseException { //格式化:从 Date 到 String Date d = new Date(); // SimpleDateFormat sdf = new SimpleDateFormat(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String s = sdf.format(d); System.out.println(s); System.out.println("--------"); //从 String 到 Date String ss = "2048-08-09 11:11:11"; //ParseException SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dd = sdf2.parse(ss); System.out.println(dd); } }
Calendar类
其日历字段已使用当前日期和时间初始化:Calendar rightNow = Calendar.getInstance();
Calendar是一个抽象类,不能直接构造,可以用.getInstance() 方法构造(多态的形式)。-
Calendar类常用方法
public int get(int field) 返回给定日历字段的值
public abstract void add(int field, int amount) 根据日历的规则,将指定的时间量添加或减去给定的日历字段
public final void set(int year,int month,int date) 设置当前日历的年月日
注意:MONTH范围是0~11,所以实际月份是MONTH+1
例子
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR); //Calendar.YEAR =1;.get(1)代表返回年的值。
int month = c.get(Calendar.MONTH)+1; //Calendar.MONTH=2;
int date = c.get(Calendar.DATE); //Calendar.DATE=5;
System.out.println(year + "年" + month + "月" + date + "日");
//需求1:3年前的今天
c.add(Calendar.YEAR,-3);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH) + 1;
date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
//设置当前日历的年月日
c.set(2050,10,10);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH) + 1;
date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
异常
异常的体系
- Throwable
- Error
- Exception
- RuntimeException
- 非RuntimeException
- Error严重问题,不需要处理
- Exception 称为异常类,它表示程序本身可以处理的问题
- RuntimeException 在编译器不检查
- 非RuntimeException 编译器就必须处理,否则程序不能通过编译
try-catch方式处理异常
-
定义格式
try { 可能出现异常的代码; } catch(异常类名 变量名) { 异常的处理代码; }
-
执行流程
- 程序从 try 里面的代码开始执行
- 出现异常,就会跳转到对应的 catch 里面去执行
- 执行完毕之后,程序还可以继续往下执行
Throwable成员方法(应用)##
-
常用方法
方法名 说明 public String getMessage() 返回此 throwable 的详细消息字符串 public String toString() 返回此可抛出的简短描述 public void printStackTrace() 把异常的错误信息输出在控制台
throws方式处理异常(应用)
- 定义格式
public void 方法() throws 异常类名 {
}
-
注意事项
- 这个throws格式是跟在方法的括号后面的
- 编译时异常必须要进行处理,两种处理方案:try...catch …或者 throws,如果采用 throws 这种方案,将来谁调用谁处理
- 运行时异常可以不处理,出现问题后,需要我们回来修改代码
throws和throw的区别
- throws
- 用在方法声明后面,跟的是异常类名
- 表示抛出异常,由该方法的调用者来处理
- 表示出现异常的一种可能性,并不一定会发生这些异常
- throw
- 用在方法体内,跟的是异常的对象名
- 表示抛出异常,由方法体内的语句处理
- 执行throw一定抛出了某种异常
自定义异常(应用)
- 例子
- 自定义异常类
public class ScoreException extends Exception {
public ScoreException() {}
public ScoreException(String message) {
super(message);
}
}
-
老师类
public class Teacher { public void checkScore(int score) throws ScoreException { if(score<0 || score>100) { // throw new ScoreException(); throw new ScoreException("你给的分数有误,分数应该在0-100之间"); } else { System.out.println("成绩正常"); } } }
-
测试类
public class Demo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入分数:"); int score = sc.nextInt(); Teacher t = new Teacher(); try { t.checkScore(score); } catch (ScoreException e) { e.printStackTrace(); } } }
Collection集合
集合体系结构
- 集合
- collection(单列)
- list(可重复,有序列)
- ArrayList (查询快,增删慢)
- LinkedList (查询慢,增删快)
- set (不可重复)
- HashSet (无序)
- LinkedHashSet (有序)
- TreeSet (会按一定规则排序)
- HashSet (无序)
- list(可重复,有序列)
- map(双列)
- HashMap
Collection集合基本使用
-
Collection集合概述
- 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
创建Collection集合的对象
Collection<String> c = new ArrayList<String>();Collection集合的常用方法【应用】
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
Collection集合的遍历
- 迭代器的介绍
- 迭代器,集合的专用遍历方式
Collection<String> c = new ArrayList<>();
//返回此集合中元素的迭代器,地址指向it
Iterator<String> it = c.iterator();
//用while循环改进元素的判断和获取
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
List集合概述和特点
- List集合概述
- 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- List集合特点
- 有索引
- 可以存储重复元素
- 元素存取有序
List集合的特有方法
方法名 | 描述 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
2.5列表迭代器【应用】##
-
ListIterator介绍
- 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
- 用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
-
示例代码
public class ListIteratorDemo { public static void main(String[] args) { //创建集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //获取列表迭代器 ListIterator<String> lit = list.listIterator(); while (lit.hasNext()) { String s = lit.next(); //用listIterator()方法获得的列表迭代器在遍历期间加元素 不会发生并发修改异常。 if(s.equals("world")) { lit.add("javaee"); } } System.out.println(list); } }
增强for循环
for(String s : list) {
System.out.println(s);
}
List集合子类的特点##
-
ArrayList集合
底层是数组结构实现,查询快、增删慢
-
LinkedList集合
底层是链表结构实现,查询慢、增删快
LinkedList集合的特有功能##
-
特有方法
方法名 说明 public void addFirst(E e) 在该列表开头插入指定的元素 public void addLast(E e) 将指定的元素追加到此列表的末尾 public E getFirst() 返回此列表中的第一个元素 public E getLast() 返回此列表中的最后一个元素 public E removeFirst() 从此列表中删除并返回第一个元素 public E removeLast() 从此列表中删除并返回最后一个元素
Set集合
Set集合概述和特点
- Set集合的特点
- 没有索引、只能通过迭代器或增强for循环遍历
- 不能存储重复元素
- HashSet集合特点
- 底层是哈希表
- 储存无序
- LinkHashSet集合特点
- 储存有序
//创建集合对象
Set<String> set = new HashSet<String>();
哈希值
-
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
-
哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
HashSet集合保证元素唯一性源码分析
-
HashSet集合保证元素唯一性的原理
1.根据对象的哈希值计算存储位置
如果当前位置没有元素则直接存入
如果当前位置有元素存在,则进入第二步
2.当前元素的元素和已经存在的元素比较哈希值
如果哈希值不同,则将当前元素进行存储
如果哈希值相同,则进入第三步
3.通过equals()方法比较两个元素的内容
如果内容不相同,则将当前元素进行存储
如果内容相同,则不存储当前元素
HashSet集合存储学生对象并遍历
-
案例需求
- 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
- 要求:学生对象的成员变量值相同,我们就认为是同一个对象
【注意点】:要对对象的类的hashCode()和equals()方法重写,才能保证集合内对象唯一性
-
代码实现
-
学生类
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 boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
-
测试类
public class HashSetDemo02 { public static void main(String[] args) { //创建HashSet集合对象 HashSet<Student> hs = new HashSet<Student>(); //创建学生对象 Student s1 = new Student("林青霞", 30); Student s2 = new Student("张曼玉", 35); Student s3 = new Student("王祖贤", 33); Student s4 = new Student("王祖贤", 33); //把学生添加到集合 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //遍历集合(增强for) for (Student s : hs) { System.out.println(s.getName() + "," + s.getAge()); } } }
-
LinkedHashSet集合概述和特点
-
LinkedHashSet集合特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
TreeSet集合概述和特点
-
TreeSet集合概述
- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator) :根据指定的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合
- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
自然排序Comparable的使用
-
案例需求
- 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
实现步骤
- 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
- 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
-
代码实现
-
学生类
public class Student implements Comparable<Student> { //继承Comparable接口,接口带泛型 private String name; private int age; .... @Override public int compareTo(Student s) { //重写compareTo方法 /* 如果返回值大于0,括号内对象放在序列最后一个对象后面; 如果返回值等于0,表示对象重复,则对象不添加进集合; 如果返回值小于0,括号内对象和序列最后一个对象对换位置; */ int num = this.age - s.age; //this.age在前-->正序; // int num = s.age - this.age; //this.age在后-->倒序; //年龄相同时,按照姓名的字母顺序排序 int num2 = num==0?this.name.compareTo(s.name):num; return num2; } }
-
测试类
public class TreeSetDemo02 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts = new TreeSet<Student>(); //创建学生对象 Student s1 = new Student("xishi", 29); .... //把学生添加到集合 ts.add(s1); .... //遍历集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
-
比较器排序Comparator的使用
-
案例需求
- 存储学生对象并遍历,创建TreeSet集合使用带参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
实现步骤
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
-
代码实现
-
学生类
public class Student { private String name; private int age; .... }
-
测试类
public class TreeSetDemo { public static void main(String[] args) { //创建集合对象,匿名内部类重写compare方法 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //注意,这里重写compare //this.age - s.age //s1,s2 int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; //注意,这里调用的是compareTo()方法 return num2; } }); //创建学生对象 Student s1 = new Student("xishi", 29); .... //把学生添加到集合 ts.add(s1); .... //遍历集合 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
-
泛型概述和好处
-
泛型概述
是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
-
泛型的好处
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换
泛型类
-
示例代码
-
泛型类
public class Generic<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
-
测试类
public class GenericDemo { public static void main(String[] args) { Generic<String> g1 = new Generic<String>(); g1.setT("林青霞"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<Integer>(); g2.setT(30); System.out.println(g2.getT()); } }
-
-
示例代码
-
带有泛型方法的类
public class Generic { public <T> void show(T t) { System.out.println(t); } }
-
泛型接口
-
示例代码
-
泛型接口
public interface Generic<T> { void show(T t); }
-
类型通配符
-
类型通配符的作用
为了表示各种泛型List的父类,可以使用类型通配符
-
类型通配符的分类
- 类型通配符:<?>
- List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
- 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
- 类型通配符上限:<? extends 类型>
- List<? extends Number>:它表示的类型是Number或者其子类型
- 类型通配符下限:<? super 类型>
- List<? super Number>:它表示的类型是Number或者其父类型
- 类型通配符:<?>
可变参数
-
可变参数介绍
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名) { }
public void method(String... s){ } //s是个数组
Map集合
Map集合概述和特点【理解】
-
Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
- 键值对映射关系
- 一个键对应一个值
- 键不能重复,值可以重复
- 元素存取无序 !!!!!!!!!!!!!!!!!!!!!!
Map集合的基本功能【应用】
-
方法介绍
方法名 说明 V put(K key,V value) 添加元素 修改元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean containsKey(Object key) 判断集合是否包含指定的键 boolean containsValue(Object value) 判断集合是否包含指定的值 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中键值对的个数
Map集合的获取功能【应用】
-
方法介绍
方法名 说明 V get(Object key) 根据键获取值 Set<K> keySet() 获取所有键的集合 Collection<V> values() 获取所有值的集合 Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
Map集合的遍历(方式1)【应用】
-
遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 把所有的丈夫给集中起来
- 遍历丈夫的集合,获取到每一个丈夫
- 根据丈夫去找对应的妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
步骤分析
- 获取所有键的集合。用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
Map集合的遍历(方式2)【应用】
-
遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 获取所有结婚证的集合
- 遍历结婚证的集合,得到每一个结婚证
- 根据结婚证获取丈夫和妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
步骤分析
- 获取所有键值对对象的集合
- Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
- 获取所有键值对对象的集合
集合嵌套之ArrayList嵌套HashMap
-
案例需求
- 创建一个ArrayList集合,存储三个元素,每一个元素都是HashMap
- 每一个HashMap的键和值都是String,并遍历。
集合嵌套之HashMap嵌套ArrayList
-
案例需求
- 创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList
- 每一个ArrayList的元素是String,并遍历。
Collections集合工具类
Collections概述和使用【应用】
-
Collections类的作用
是针对集合操作的工具类
-
Collections类常用方法
方法名 说明 public static void sort(List<T> list) 将指定的列表按升序排序 public static void reverse(List<?> list) 反转指定列表中元素的顺序 public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
ArrayList集合存储学生并排序【应用】
-
案例需求
- ArrayList存储学生对象,使用Collections对ArrayList进行排序
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
代码实现
-
测试类
public class CollectionsDemo02 { public static void main(String[] args) { //创建ArrayList集合对象 ArrayList<Student> array = new ArrayList<Student>(); //创建学生对象 Student s1 = new Student("linqingxia", 30); .... //把学生添加到集合 array.add(s1); .... //使用Collections对ArrayList集合排序 //sort(List<T> list, Comparator<? super T> c) Collections.sort(array, new Comparator<Student>() { //传入array集合和Comparator方法并 //重写 @Override public int compare(Student s1, Student s2) { //按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序 int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); //遍历集合 for (Student s : array) { System.out.println(s.getName() + "," + s.getAge()); } } }
-
File类
File类概述和构造方法【应用】
-
File类介绍
- 它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
File类的构造方法
方法名 说明 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例 File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例 示例代码
public class FileDemo01 {
public static void main(String[] args) {
//File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
File f1 = new File("E:\\itcast\\java.txt");
System.out.println(f1);
//File(String parent, String child):从父路径名字符串和子路径名字符串创建新的 File实例。
File f2 = new File("E:\\itcast","java.txt");
System.out.println(f2);
//File(File parent, String child):从父抽象路径名和子路径名字符串创建新的 File实例。
File f3 = new File("E:\\itcast");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
File类创建功能【应用】
-
方法分类
方法名 说明 public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 public boolean mkdir() 创建由此抽象路径名命名的目录 public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
File类判断和获取功能【应用】
-
判断功能
方法名 说明 public boolean isDirectory() 测试此抽象路径名表示的File是否为目录 public boolean isFile() 测试此抽象路径名表示的File是否为文件 public boolean exists() 测试此抽象路径名表示的File是否存在 -
获取功能
方法名 说明 public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串 public String getPath() 将此抽象路径名转换为路径名字符串 public String getName() 返回由此抽象路径名表示的文件或目录的名称 public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组 public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组
File类删除功能【应用】
-
方法分类
方法名 说明 public boolean delete() 删除由此抽象路径名表示的文件或目录
-
绝对路径和相对路径的区别
- 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\itcast\java.txt
- 相对路径:必须使用取自其他路径名的信息进行解释。例如:myFile\java.txt
递归
递归【应用】
-
递归的介绍
- 以编程的角度来看,递归指的是方法定义中调用方法本身的现象
- 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
- 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
-
递归的基本使用
public class DiGuiDemo { public static void main(String[] args) { //回顾不死神兔问题,求第20个月兔子的对数 //每个月的兔子对数:1,1,2,3,5,8,... //方法一(普通): int[] arr = new int[20]; arr[0] = 1; arr[1] = 1; for (int i = 2; i < arr.length; i++) { arr[i] = arr[i - 1] + arr[i - 2]; } System.out.println(arr[19]); //方法二(递归): System.out.println(f(20)); //调用下面定义的f()方法 } /* 递归解决问题,首先就是要定义一个方法: 定义一个方法f(n):表示第n个月的兔子对数 那么,第n-1个月的兔子对数该如何表示呢?f(n-1) 同理,第n-2个月的兔子对数该如何表示呢?f(n-2) StackOverflowError:当堆栈溢出发生时抛出一个应用程序递归太深 */ public static int f(int n) { if(n==1 || n==2) { //设定递归出口 return 1; } else { return f(n - 1) + f(n - 2); } } }
-
递归的注意事项
- 递归一定要有出口。否则内存溢出
- 递归虽然有出口,但是递归的次数也不宜过多。否则内存溢出
递归求阶乘【应用】
-
案例需求
用递归求5的阶乘,并把结果在控制台输出
-
代码实现
public class DiGuiDemo01 { public static void main(String[] args) { //调用方法 int result = jc(5); //输出结果 System.out.println("5的阶乘是:" + result); } //定义一个方法,用于递归求阶乘,参数为一个int类型的变量 public static int jc(int n) { //在方法内部判断该变量的值是否是1 if(n == 1) { //是:返回1 return 1; } else { //不是:返回n*(n-1)! return n*jc(n-1); } } }
递归遍历目录【应用】
-
案例需求
给定一个路径(E:\itcast),通过递归完成遍历该目录下所有内容,并把所有文件的绝对路径输出在控制台
-
代码实现
public class DiGuiDemo02 { public static void main(String[] args) { //根据给定的路径创建一个File对象 // File srcFile = new File("E:\\itcast"); File srcFile = new File("E:\\itheima"); //调用方法 getAllFilePath(srcFile); } //定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的File对象 public static void getAllFilePath(File srcFile) { //获取给定的File目录下所有的文件或者目录的File数组 File[] fileArray = srcFile.listFiles(); //获得目录内所有文件夹和文件的File对象组成的数组 //遍历该File数组,得到每一个File对象 if(fileArray != null) { //防止目录内容为null,报错 for(File file : fileArray) { //判断该File对象是否是目录 if(file.isDirectory()) { //是:递归调用 getAllFilePath(file); } else { //不是:获取绝对路径输出在控制台 System.out.println(file.getAbsolutePath()); } } } } }