本帖最后由 小石姐姐 于 2018-4-20 09:36 编辑
笔记总结
Day05 常用API,日期的转换,包装类,正则表达式常用APIObject类
所有的类一开始没有继承其他的类之前都默认继承Object类 一个类虽然继承了其他的类,但是他的父类总有一个是会继承Object类的,所以类一定会继承Object类
String toString():返回该对象的字符串表示 return getClass().getName()+"@"+Integer.toHexString(hashCode()); getClass();返回一个字节码对象 getName();返回字节码的名字 toHexString方法就是以十六进制(基数16)无符号整数形式返回一个整数参数的字符串表示形式 hashCode():返回该对象的哈希码值(内部地址值)
获取字节码文件对象的方式注意:同一个类下创建的对象的字节码值是一样的,例如一个类创建两个对象,分别是c1 c2 ,那么 c1.getClass() =c2.getClass(); 学习反射的时候,我们可以获得任意一个类的对象,并且调用它的方法和成员变量 object中的equals因为Object 中的equals比的是我们new 类的对象的地址值,每个地址值都不相同,所以返回肯定都是false 这里我们就需要重写equals方法 比较Person p=new Person("liming",18); Person p2=new Person("liming",18); p和p2是否相等
//因为所有的类都继承自Object类,所以 Object b类就是继承Object类的子类
//传入一个Object类的对象
public boolean equals(Object b){
//为了提高效率 当前对象和传递进来的地址值相等的时候,那他们就相等
if(this==b){
return true;
}
//提高代码的健壮性,就是安全性,看看他们两个类的类型是否相同
if(this.getClass()!=b.getClass()){
return false;
}
//将父类强转成子类
Person per=(Person)b;
//分别比较类中的成员变量
if(!this.name.equals(per.name)){
return false;
}
if(this.age!=per.age){
return false;
}
//两者都能执行下去,那么就返回true
return true;
}
System类常用的成员方法
* 类字段,System.out.println(),out就是类字段,
* err 错误输入流
* in 输入流
* out 输出流
* 格式 System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src表示源数组
dest表示目标数组
srcPos表示起始要复制的元素的索引值
destPos表示从目标文件的哪个索引值开始复制,
length表示要复制的数组的长度
* 毫秒值转----Date
* Date d=new Date(毫秒值);
* System.out.println(d);
* 设置
* 返回值是void.参数long
* 构造方法也可以
* void setTime(long time);
* Date(long date)
*
* Date---毫秒值
* 获取
* 返回long.无参数
* long.setTime() 设置时间
* long getTime()
## 举例 :
*当有要求输出当前时间点
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss:SS")
Date date =new Date();
String s=sdf.format(date);
System.out.println(s); //输出2018年04月07日18:37:54:721
解析:
Date d=new Day("")
String s=abf.parse();SimpleDateFormat 用于格式化日期 他的父类是Format 他的子类是simpleDateFormat 格式化: Date---String 用parse方法来将String类型的日期文本转换为Date日期对象 date对象接收= new SimpleDateFormat.parse(String text, ParsePosition pos) 2049-8-26 2049年8月26日 解析: String ---Date "2049-8-26" Date parse(String source) 因为字符串不能用来算数,所以我们就需要调用Date方法来转换成毫秒值来实现 注意:Exception in thread "main" java.text.ParseException: Unparseable date: "2018年04月07- 18:37:54:721" 解析成字符串输出的时候,字符串的模式必须和构建对象的模式一样
速记小技巧 : 00年00月00日 就是4个小姨2个大美眉和2个小弟弟 包装类的概述和基本使用
由于基本数据类型只能做一些简单的操作和运算,所以Java为我们包装了基本数据类型,为每种基本数据类型提供了包装类.
包装类就是封装了基本数据类性的类,为我们提供了更多复杂的方法和一些变量
我们有四类八种基本数据类型他们分别都包装了基本类型
byte Byte
short Short
char Character
int Integer
long Long
float Float
double Double
boolean Bollean
Integer
相互转换
int a = new Integer("60").intValue();
String---int
int---String
Integer的转换方法
Integer(int value)
String s=new Integer().Integer(60);
Integer(String s)
int intValue()
static int parseInt(String s)
static String toString(int i)
Integer的构造方法
//Integer(String s)
Integer i=new Integer("10");
System.out.println(i);
将字符串转换为int类型
Integer i=new Integer("60");
int a = i.intValue();
System.out.println(a + 30);
* 因为我们需要在不创建Integer对象的情况下来转换字符串,所以我们必须选择一个静态方法
Integer 相互转换
// 方式1; int类型接收 =new Integer("字符串").intValue();
// 方式2;static int parseInt(String s);
// String---int
//
// int---String
// 方式1:直接加空字符串"" + int
// 方式2: 用toString方法
// 方式3: static void toString(int i);
// Integer的构造方法
// Integer(Strings)
// Integer i=new Integer("10");
// System.out.println(i);
// 将字符串转换为int类型
// int a = new Integer("60").intValue();
// System.out.println(a + 30);
//static int parseInt(String s);包装类自动装箱和拆箱 JDK1.5的特性
自动装箱就是基本数据类型转引用类型
自动拆箱就相当于将引用类型转换为基本数据类型
Interger i=10;
Interger i2=20;
Interger i3=i+i2;
//Integer i3 = new Integer(i.intValue()+i2.intValue());正则表达式验证方法正则表达式验证方法 * Pattern类,在API中查询Pattern类查询正则表达式 比较格式: boolean matches (String regex):判断是否符合正则表达式的规范 日期中常用的转换方法 1)Date对象转转毫秒值
Date d=new Date();
long 毫秒变量接收 = d.getTime(); 2)毫秒值转Date对象 setTime没有返回值,所以不需要Date对象接收
Date d=new Date();
d.setTime(d.getTime()); 3)String日期字符串转Date对象 (叫做解析)
调用SimpleDateFormat方法parse(); 返回一个Date对象,
定义SimpleDateFormat 的对象
SimpleDateFormat sdf=new SimpleDateFormat("日期规范");
Date d=sdf.prase("日期字符串对象或者日期字符串的String常量") 4)Date对象转String
Date d =new Date();
String s=adf.format(d);
System.out.println(s) ;//我们此时输出的就是符合我们定义的规范的日期,输出日期字符串巧记:毫转时间用set,时间换毫秒用get(并且long接收), 5)Calendar方法 用于获取年 月 日 小时 分钟 秒 注意: 有意Calendar是一个抽象类 ,要想调用Calendar 的对象,我们可以直接调用它的静态方法Calendar cal= Calendar.getInstance(); 用Calendar对象来接收 注意: Calendar cal= Calendar.getInstance(); Date对象转Calendar,这里主要使用来获取改变的Date日期,然后用Calendar来获取并且输出 cal.setTime(Date对象); 例如: cal.setTime(new Date()); 获取 int year=cal .get(Calendar.YEAR) ;//实际上就是调用Calendar中的成员变量 修改 cal.set(Calendar.YEAR, 要修改成的年份); 添加 cal.add(Calendar.MONTH,要修改的月份,如果是负数,那就是日期待退多少);
Day06 List集合,迭代器,泛型,Collection常用功能ArryList 集合的体系结构 体系结构: 1)因为不同功能的数据结构(数据的组织,存储方式),所以Java 为我们提供了不同的集合 2)但是不同的集合它们的功能都是相似的,我们可以不断的向上抽取,提取共性 Collenction常用功能Collection类 Collection c=new ArrayList(); add 添加 clear 清除 清空 boolean contains (Object o);判断集合中是否包含指定元素 bollean remove(); 如果删除成功,则返回true bollean isEmpty(); 是否为空 如果有元素,则返回false Object[] toArray():将集合转换成一个Object类型的数组
for(int =0 ; i<objs.lenth;i++){
System.out.println(objs);
}迭代器 迭代器中的方法 首先迭代器 Iterator it=集合对象. iterator(); for(it.hasNext())}{ System.out.println(集合对象.next()); } 实际上就是遍历集合 构造方法 boolean hasNext(); 是否存在下一个元素 E next(); 返回迭代的下一个元素 void remove(); 从迭代器指向的collection中移除迭代器返回的最后一个元素 迭代的意思: 就是重复执行某一操作,类似于循环 //迭代遍历集合 Iterator iterator=new Iterator(); for(iterator.hasNext()) { System.out.println(list.next()); } * 用迭代来判断集合中的元素,并且用集合 来操作添加元素,会报错
* 报错的原因是,迭代实际上是集合的副本,集合中没有的副本,我们用迭代就执行不了,迭代器依赖于集合
* 报错提示 **ConcurrentModificationException** 重点注意: 迭代器依赖于集合,相当于集合的副本 (我们通过迭代器修改集合中的元素,因为迭代器和集合是同步的) 并发修改异常迭代器的添加方法: 我们可以调用Iterator的儿子的方法来实现添加元素 List子类
List l = new ArrayList(); //创建集合对象
ListIterator li=l.ListIterator(); //迭代
while(li.hasNext()){
li.add("C++"); //用迭代器添加,因为迭代器是和集合是同步的
System.out.println(l);
}泛型
泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,就是在还没执行程序之前就会提醒你,捷键了数组的特点(类型不同,不允许存储) * 泛类就是和集合格式一样 * ArrayList<泛类,就是要存储的数据类型> arr=new ArrayList<String>(); * 类的格式为 类名<E>类型的类,都可以指定泛类 泛型只存在于编译之前,编译以后,系统功能会擦出泛型 好处: 避免了类型转换的问题 可以减少黄色警告线 可以简化我们代码的书写
// 创建集合对象
Collection<Student> c = new ArrayList<Student>();
// 创建元素对象
Student s1 = new Student("张三",19);
Student s2 = new Student("李四",18);
// 添加元素对象
c.add(s1);
c.add(s2);
// 遍历集合对象
//用迭代器遍历数组
Iterator<Student> it=c.iterator();
while(it.hasNext()){
Student stu=it.next();
System.out.println(stu);
}foreachforeach 这是一个增强for循环 foreach:增强for循环.一般用于遍历集合或者数组 格式: 先创建集合对象 ArrayList arr=new ArrayList(); for(集合元素的类型 变量:集合或者数组对象){ 可以直接使用变量; } public interface Iterable<T> 实现这个接口的对象才能使用"foreach"语句
常见的数据结构数组:
一旦定义就不能改变,
查找快,增删慢.链表:由链子链接起来的一堆结点 结点: 地址值,值,下一个结点的地址值1,2,3,4,5 例如:
| 0x0011 | 1 | 0x0022 |
| 0x0022 | 2 | 0x0033 |
| 0x0033 | 3 | 0x0044 |
| 0x0044 | 4 | 0x0055 |
| 0x0055 | 5 | |如何获取结点3?如何获取结点3? 只能遍历链表,然后一个个查看, 要在结点2后面添加一个新的结点8? 把结点2的下一个结点地址值修改为结点8的地址值,把新节点8的下一个地址值改为3结点的地址值 缺点:查询慢增删快 栈和队列的特点
栈是先进后出,
队列是先进先出列表List List 的元素排列顺序是依次排列和Array List一样 常用方法: 先创建对象 List list=new ArrayList(); 添加: void add (int index,E element) list.add(); 修改: E remove (int index):将指定索引位置的元素替换,并且返回原来的元素 list.set(0,"android"); 获取:E get (int index)根据索引返回元素 list.get(); 注意: 在获取的时候也不能发生越界,即获取它不存在的索引的元素 List的子类的特点,和ArrayList的特点
Array List的底层是数组 特点,查询快,增删慢 LinkeList的底层是链表 特点,查询慢,增删快 如果不清楚使用什么来对数组进行操作,那么我们一般选择ArrayList LinkeList的元素排列顺序是,来得越早,你越靠后** LinkeList的特有功能 void addFirtst(E e) void addLast(E e) E getFirst(); E getLast(); E removeFirst(); E removeLast();
Day 07 Set接口 Map键值对Set接口的特点使用HashSet字符串并遍历 set的特点: * 无序(存储时的顺序有可能和输出的顺序不同) * set存储时不允许重复(要求元素唯一) * 因为它存储时时无序的,所以它没有索引值
set方法不存在索引添加元素的特征
HashSet的父类是Collection(存储\收集的意思)HashSet
在同一类当中,创建的所有对象的hash码值都不相同
所以当判断这两个对象是否相同的时候,先判断他们的Hash码值,我们发现,当hashCode方法永远返回整数1时,所有对象的hash都是一样的 有一些对象他的成员变量完全不同,但是他们还是要进行hash和equals方法的比较 如果我们可以让成员变量不同的对象,他们的hash值也不同,着样就不用在进行多余的比较了 从而可以提高我们程序的效率 我们可以尝试让hashCode方法的返回值和对象成员变量有关,我们需要返回成员变量之和让基本数据类型直接相加(这里我们需要重写hashCode方法), 然后用引用数据类型获取hashCode方法返回值后再相加(boolean类型不可以参与运算)
ha'shCode方法优化
如果让hashCode()方法返回一个固定值,那么每个新添加的元素都要调用equals(Object obj)方法比较,那么效率较低 只需要让不同属性的值的元素产生不同的哈希值,那么就可以不再调用equals方法比较提高效率 重写equals方法
重写equals时,如果我们传入的参数是一个没有泛型的类型,
那么我们向下转型成当前类的对象有可能会报错,所以我们这里需要判断当前类对象和传入的类的对象,
//重写equals方法
public boolean equals(Object obj) {
System.out.println("-----");
//如果泛型不同,我们需要提高效率
if(this==obj){
return true;
}
//比较传入的对象的字节码值,如果相同,则代表他们时同一个类中的变量.则不需要在比较.直接
if(this.getClass()!=obj.getClass()){
return false;
}
//我们需要先向下转型成当前类的对象
Person p =(Person)obj;
//接下来我们比较他们的年龄,如果当前的成员变量与初始化的成员变量值相同
if(this.age!=p.age){
return false;
}
//接下来判断行姓名
if (this.name!=p.name) {
return false;
}
//如果以上条件都不执行,则默认他们相同
return true;
}Collections工具类的方法static int binarySearch(List list,Object key); 二分法(参数中只能是List集合,因为Set等集合,他们是无序的)不断的取中间值,如果中间值小于给出的数,那么就只比较中间值以后的,如果中间值大于给出的数,那么就判断这个 static void fill (List list,Object obj);使用指定元素替换指定列表中的所有元素 static void copy(List dest ,List src):把源列表中的数组覆盖到指定目标列表(注意:目标列表长度至少等于元列表的长度) static void reverse(List list): 反转, .3.1 案例代码四:package com.itheima_03;
import java.util.ArrayList;import java.util.Collections;import java.util.List; /*
public class CollectionsDemo {
public static void main(String[] args) {
//static void swap(List list, int i, int j) :将指定列表中的两个索引进行位置互换
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(4);
Collections.swap(list, 0, 1);
System.out.println(list);
}
private static void method6() {
//static void sort(List<T> list) :按照列表中元素的自然顺序进行排序
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(4);
list.add(3);
list.add(2);
Collections.sort(list);
System.out.println(list);
}
private static void method5() {
//static void shuffle(List list):傻否,随机置换
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Collections.shuffle(list);
System.out.println(list);
}
private static void method4() {
//static void reverse(List list) :反转
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Collections.reverse(list);
System.out.println(list);
}
private static void method3() {
//static void fill(List list, Object obj) :使用指定的对象填充指定列表的所有元素
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list);
Collections.fill(list, "android");
System.out.println(list);
}
private static void method2() {
//static void copy(List dest, List src) :是把源列表中的数据覆盖到目标列表
//注意:目标列表的长度至少等于源列表的长度
//创建源列表
List<String> src = new ArrayList<String>();
src.add("hello");
src.add("world");
src.add("java");
//创建目标列表
List<String> dest = new ArrayList<String>();
dest.add("java");
dest.add("java");
dest.add("java");
dest.add("java");
Collections.copy(dest, src);
System.out.println(dest);
}
private static void method() {
//static int binarySearch(List list, Object key) 使用二分查找法查找指定元素在指定列表的索引位置
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
int index = Collections.binarySearch(list, 4);
System.out.println(index);
}} Map方法构造方法 public interface Map<K,V> 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 特点: 键是唯一的 键不能重复,值可以 键是无序的 Collection 和Map的区别?
Map是一个双列集合,常用语处理有对应关系的数据,key时不可以重复的,我们也称之为夫妻对集合Collection:是单列集合,Collection有不同的自体系,有的允许重复有索引有序,有的不允许重复而且无序,那么我们也称之为单身汉集合
Map的常用功能
添加
// V put(K key, V value) 添加元素方法
System.out.println(map.put("it001", "张五"));
System.out.println(map.put("it002", "李明"));
System.out.println(map.put("it003", "小明"));
判断
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
删除
void remove("it002"); 清除指定的键 的键值
void clear() 清除所有的键值对
遍历
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。 Map的第一种遍历方式: keySet();先获取所有的键,然后根据键来找值
Set<E> st=map.keySet();
Set<Student> key1 = map.keySet();
for (Student student : key1) {
System.out.println(student.toString());
}
Map的第二种遍历方式: entrySet();(相当于结婚证)
//定义一个Map
Map<String,Integer> map=new HashMap<String,Integer>();
map.add("小明",18);
map.add("小张",19);
map.add("小米",20);
//创建set集合获取结婚证
HashSet<Entry<Student, String>> entrySet = map.entrySet();
for (Entry<Student, String> entry : entrySet) {
System.out.println("同学姓名"+entry.getKey());
System.out.println("同学年龄"+entry.getValue());
可变参数
在类型明确,参数数量不确定的时候. java可以把多个参数直接转换成数组 但是可以在可变参数的前面添加 可变参数可以给多个,或者一个也不给也不会报错
例如:
sum(1,2,3,4,5,6);
public static int sum(int...arr){
for(int i=0; i<arr.length; i++){
sum+=i;
}
return sum; Day08 异常,递归异常处理异常的体系结构
Java.lang.Throwable(最顶层)
|_Error(不应该试图捕获的严重问题,不能处理的异常)
|Exception(可以处理的异常) #编译时异常:编译时期就会发生的异常
|RuntimeException #运行时异常:编译时正常,运行时才会发生的异常异常的处理方式:
JVM处理异常的方式:
如果异常没有处理,jvm会帮我们进行处理,他会把异常的类型,原因还有位置显示在命令行,并且还终止了程序,异常后面的代码将不再执行
try...catch语句我们自己进行异常处理的方式:
try{
有可能会出现问题的代码;
}catch(ArithmeticException ae(填写异常)){
处理异常;
}try...catch的执行顺序 首先执行try语句 如果发现异常,异常下面的代码不再执行,直接跳入catch语句中,catch语句结束后,整个try...catch语句结束 如果没有发现异常,那么catch语句中的代码不会执行 在try..catch语句中,发生的异常,他们存在子父类关系,那么子类异常在上,父类异常在下 抛出编译时异常:throws 主动抛出异常:throw
异常分类
两大类
|运行时期异常:RuntimeException的子类就是运行时期异常,在编译时期可以自由选择处理或不处理
|编译时期异常:是Exception的子类,非RuntimeException的子类自定义异常应用场景 当我们在捕获异常时,系统所给的异常提示满足不了我们的需求,这时候我么你需要自己定义自定义异常; 自定义异常: 实际上就是我们自定义运行时期异常类和编译时期异常类,并分别实现他们对应的父类的有参和无参构造; 创建运行时期异常的子类 // 子定义运行时期子类,并且实现父类有参和无参方法 class MyRunException extends RuntimeException {
public MyRunException() {
super();
// TODO Auto-generated constructor stub
}
public MyRunException(String message) {
super(message);
// TODO Auto-generated constructor stub
} 创建编译时期异常类 // 子定义编译时期子类,并且实现父类有参和无参方法class MyException extends Exception {
public MyException() {
super();
}
public MyException(String message) {
super(message);
}}
多异常处理多异常的捕获:
多异常捕获中catch的顺序
如果被捕获的异常类没有继承关系, 则catch的顺序可以随意定义 如果异常是继承关系的类, 必须子类异常在上, 父类异常在下
多个catch代码块的执行逻辑
try代码块中抛出的异常, 如果catch中有对应的具体异常, 则执行对应的catch代码块. 其他catch代码块不会执行(类似于if...else if, switch...case) try代码块中抛出的异常, 如果catch中没有对应的具体异常, 则所有catch代码块都不会执行. 相当于异常没有捕获, 仍然会导致程序终止
try {
// 可能发生异常的代码
} catch (异常类型1 异常对象名1) {
// 处理异常1的代码
} catch (异常类型2 异常对象名2) {
// 处理异常2的代码
}
// 格式
try {
// 可能抛出异常的代码
} catch (异常类型1 | 异常类型2 异常变量名) {
// 异常处理代码
if (异常变量名 instanceof 异常类型1) {
// 处理异常类型1
} else if (异常变量名 instanceof 异常类型2) {
// 处理异常类型2
}
}
// 一般这样处理是因为2种异常的处理方式相同, 才合并写; 否则可以使用catch语句方式分别处理Throwable的常用方法Throwable类
常用成员方法
String getMessage(): 异常的信息. 没有原因返回null String toString(): 异常的类型和原因 void printStackTrace(): 使用标准错误输出流打印异常信息
finally概述和引用场景
- finally关键字
- 作用:
- 与try...catch配合, 无论异常是否被捕获, 最终都会执行finally代码块中的代码
- 应用场景:
- 如IO流的关流操作, 无论IO操作过程中是否出现异常, 最终都要关流, 避免程序占用资源. 所以一般都在finally代码块中进行关流操作
- 格式:
```java
try {
// 可能发生异常的代码
} catch (异常类型 异常变量名) {
// 对捕获异常的处理
} finally {
// 无论是否捕获异常, 都需要执行的操作
}
```
- 提前认识一下IO流操作的标准写法:
```java
FileWriter fw = null; // 在try代码块外初始化, 这样finally中才能访问到
try {
fw = new FileWriter("a.txt"); // 创建输出流对象, 会抛出FileNotFoundException异常
fw.write("hello"); // 会抛出IOException
} catch (IOException e) { // IOException是FileNotFoundException的父类, 可以多态形式捕获
// 处理异常
} finally {
// 关闭流
if (fw != null) { // 判断fw是否为null, 避免空指针异常
try {
fw.close(); // 关闭流, 会抛出IOException
} catch (IOException e) {
e.printStackTrace(); // 打印异常. 开发中一般不会打印出来, 而是存入日志
}
}
}
```
•递归的注意事项: 递归一定要有出口,内存溢出 递归次数不宜过多,内存溢出
斐波那契列数;
public class Test2 {
public static void main(String[] args) {
int number1=method(10);
int number2=method(9);
//求斐波那契列数
double d=number2*1.0/number1;
//输出值
System.out.println(d);
}
public static int method(int n) {
if(n==1){
return 1;
}else if(n==2){
return 1;
}else {
//假如传入的数据每次都不符合if和else if的条件,
//那他就一直调用自身方法相加
return method(n-1)+method(n-2);
}
}
}
递归优点 减少代码的书写 递归的缺陷: 代码识辨识性差,一般情况下使用for循环
|