Object类
Object类是所有类的超类“父类”;
直接打印tostring 打印出来的是一个地址值。其实直接打印对象的名字就是直接调用
了对像的tostring方法。
看一个类是否重写了同string方法 直接打印一个类的对象名称即可 如果没有重写tostring
打印出来就是对象的默认地址。如果重写了 打印出来就按照重写的方法打印。
equals 一般是用来比较 两个对象的内容 要覆写equals
== 是一般用来用力来比较基本类型的值。
时间(date类)
在程序中时间的基本单位是 毫秒=千分之一秒。
Date()的空参方法 就是获取系统的当前日期和时间。
Date(Long 毫秒值)带参数的方法 就是把毫秒转化为时间。
Date的成员方法 long getTime() 把日期转化为毫秒
对时间进行格式化
成员方法 string format(Date date)按照指定格式,格式化为符合模式的字符串
DateFormat是一个抽象类 无法直接创建对象, 可以用其子类
构造方法 SimpleDeteFormat(string patten) String patten 传递指定的格式
模式:区分大小写的
y 年 M 月 d 日 H 时 m 分 s 秒
写对应格式 "yyyy-MM-dd HH:mm:ss"
SimpleDateFormat对象中的方法format 按照构造方法中的模式 把date日期转化为符合格式
的字符串(文本)
使用DateFormat类中的方法 parse,把文本拆分为日期
注意:parse方法声明了一个异常叫做ParseException解析异常
如果字符串和构造方法中的模式不一样,那么程序就会出现异常。
Calender类 日历类 这也是一个抽象类 里面提供了很多日历字段的方法。
System 类
currenTimeMillis()类 返回以毫秒为单位的当前时间。 一般用来计算程序执行的时间。
arrayCopy 将数组当中的指定数据拷贝到另一个数组当中去。
arraycopy的格式 System.arraycopy(被拷贝的数组名,被拷贝数组开始的位置,拷贝到的数组名字,拷贝到的数组开始的位置,拷贝的长度)
StringBuilder 字符串缓冲区 可以提高字符串效率。
格式:使用空参构造 还可以使用带参构造
StringBuilder append:田间任意类型数据的字符串形式,并返回对象自身。
需要经常拼接的字符串 最好用StringBuilder
String和StringBuilder可以相互转化
String到StringBuilder调用构造方法, StringBuilder到String用tostring方法。
包装类的概念
基本数据类型用起来非常方便, 但是没有相应的方法来操作这些数据 所以我们可以用一个类来操作这些数据。这个用来操作基本数据的类 叫做包装类。
COllection 集合
数组只能储存同一类型的的元素,它可以存储基本数据类型也可以存储对象。而集合只能存储对象,可以储存不同类型的的对象。
集合框架:学习方式 学习顶层 使用底层。 就是要学习集合顶层共性的方法,使用底层的集合。
Collection接口下有 List接口和Set接口 List接口里面有 Vector集合、Arrayllist集合和Linkedlist集合 Set接口里面有HashSet集合和LinkedHashSet集合。
Collection所有单列集合的最顶层的接口
public boolean remove() 集合中存在元素 删除元素,返回true 集合中不存在元素,删除失败返回false 集合中存在两个一样的元素智慧删除第一个。
public boolean contains() 判断集合是否含=含有当前给定对象。
public boolean ifEmpty() 判断集合是否为空。
public int size()判断集合中元素的个数。
public object[] toArray() 把集合转换为数组
public void clear()清空集合 清空集合后 集合还可以使用。
Iterator<E>迭代器 的泛型是跟着集合走的 集合是什么类型那个么 迭代器就是什么类型。
迭代器是用来对集合进行遍历的。
boolean hasNext() 判断是否到达集合的结尾 到达结尾返回false 否返回true。
E next() 取出集合中的元素。
collection接口中有一个方法,叫做iterator(),这个方法返回的就是迭代器实现的对象。
使用迭代器的步骤:
1、使用集合中的方法iterator(),获取迭代器实现的对象,使用Iterator接口接受对象(多态);
2、使用Iterator接口中的方法hasNext判断是否迭代到了末尾。
3、使用Iterator接口中的方法next取出集合中的元素。
使用迭代器取出集合中的元素是一个重复的过程 所以我们使用循环优化,用while循环。
用迭代器的时候会发生 并发修改异常 可以用Iterator接口的子接口ListIterator来解决。只有List接口下的集合才能用。
发生异常的原因:
泛型 是一种未知的数据类型 当我们不知道是什么数据类型的时候可以使用泛型。
创建一个含有泛型的类
泛型是一个未知的数据类型 当我们不知道使用什么数据类型的时候,可以使用泛型
泛型可以接收任意的数据类型,可以使用Integer,String,Student。。。。。
创建对象的时候确定泛型的类型。
定义含有泛型的方法,泛型定义在方法的修饰符之后和返回值之间。
数据结构:栈,队列,数组,链表,红黑树。
栈(stack):先进后出。 队列(queue):先进先出。
数组:查找快,增删慢。
链表:查找慢(链表中的地址不是连续的,每次查找元素都得从头查询。),增删快(因为它增加或者减少一个元素对链表的整体结构没有影响,所以增删快)。
链表分为:单向链表 是指链表只有一条链子,不能保证元素的顺序(存储元素和取出元素的顺序可能不一致)
双向链表:链表中有两条链子,有一条链子专门记录元素的顺序,是一个有序的集合。
计算机中的树:是倒着的。 里面有:二叉树(分子不超过两个)
排序树/查找树(在二叉树的基础上元素的大小是有顺序的,左子树小,右子树大)查询速度快。
平衡树:左孩子个数和右孩子个数相等。
红黑树:查询的速度非常的快,查询叶子的最大次数不能超过最小次数的二倍。
红黑树的约束:1、节点可以是红色的或者是黑色的 2、根节点是黑色的 3、叶子节点(空节点)是黑色的 4、每个红色的节点的子节点是黑色的 5、任何一个节点到每一个叶子节点的所有路径上的黑色节点个数相同。
list(接口,是继承了collection接口): 是有序的集合,带有索引,它允许存储相同的元素。
list接口中带有索引的方法:
public void add(int index,E element)指定位置添加元素
public E remove(int index)移除指定位置的元素,并返回 被移除的元素。
public E set(int index,E element)用指定元素替换指定位置上的元素,并返回被替换的元素
public E get(int index)获取指定位置的元素。
list接口的实现类 ArrayList linkedList
linkedlist集合 实现了list接口。 自己的特点:1、它的底层是一个链表结构 查询慢,增删快 2、里边包含了大量操作首位元素 的方法。
public void addFirst(E e )将指定元素插入到此列表的开头
public void addLast(E e )将指定元素插入到此列表的结尾
public void puch/pop(E e )等效于addFirst/removeFirst
public void getFirst()获取并返回第一个元素
public void getLast()获取并返回最后一个元素
public void removeFirst()移除并返回第一个元素
public void removeLast()移除并返回最后一个元素
set接口 extends collection接口
HashSet集合(实现了Set接口)
HashSet集合的特点:1、 是一个无序的集合,2、不能存储重复的元素 3、没有索不能使用带索引的方法,也不能使用普通的for循环 4、底层是一个哈希表存取速度很快。
HashSet 底层是 数组+链表+红黑树
HashSet在调用add方法的时候 回调用hashCode和equals方法。
Map集合的特点:
1、Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
2、Map集合的元素 key和value的数据类型可以相同也可以不同。
3、Map集合中key不能相同而value可以相同。
4、Map集合中的key和value是一一对应的关系。
Map的常用子类:HashMap LinkeHashMap(底层也是哈希表)
HashMap:是一个不保证顺序的集合,底层是哈希表,查询速度特别的快。
LinkeHashMap:
1、底层保存的是:哈希表+链表(保证迭代顺序)
2、是一个有序集合,存和取的顺序是一致的。
JDK1.8之前:是数组+单向链表
JDK1.8之后:数组+单向链表/红黑树(链长度超过8之后)
Map的常用方法:
1、public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
2、public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
3、public V get(Object key) 根据指定的键,在Map集合中获取对应的值。key存在返回对应的值,key不存在返回null。
4、 public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
5、public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
6、 public boolean containsKey(Object key) : 判断集合中是否包含指定的key 有返回true,不包含返回false。
遍历Map集合:Set<K> keySet() 使用Map集合当中的keySet方法,就是把Map集合中的所有的key取出来存到set集合中去。(通过键找志的方法)
遍历Map集合的第二种方法:Entry键值对对象
在Map接口中有一个内部接口Entry,当Map集合创建时,就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键与值的映射关系)
Set<Map.Entry<k.v>> entrySet()把Map集合内部的多个Entry对象取出来存到一个Set集合中。
在Map中以我们存的对象地址来判断对象是否相同,地址相同才判断为相同。
如果要通过判断内容来判断是否相同,在自定义类中重写HashSet和equals方法。
linkedHashMap 于HashMap的区别是,HashMap是无序的,而LinkedHashMap是有序的。它也不允许Key重复。
Hashtable集合 此集合的底层也是哈希表,也实现了Map接口,任何null对象都不能存到该集合中去。他是单线程集合,速度慢。被淘汰了,但是Hashtable的子类Properties依然活跃在历史舞台上,因为Perperties是唯一一个与IO流结合的集合。Hashtable的线程是安全的。
HashMap集合可以存null值和null键,之前学的所有集合都可以存null。HashMap的线程是不安全。
异常的最顶层的父类是 Throwable 它有两个子类Error和Exception
Error错误是非常严重的问题,就相当于程序得了无法治愈的毛病,必须修改代码程序才能正常运行。
Exception叫做编译期异常(写代码的时候发生的异常)
RuntimeException 运行期异常。java程序运行的过程中发生的异常。
异常处理的两种方法,throws 往上抛,最终抛给虚拟机,虚拟机会打印异常信息,并中断程序;
try。。(可能出现问题的代码)。。catch。(出现问题的处理办法)。
throw关键字可以再指定的位置抛出指定的异常。
格式:throw new xxxException(“异常产生的原因”)
注意:1、throw必须写在方法的内部
2、throw关键字后边new的对象必须是Exception或者是其子类对象
3、throw关键字抛出对象我们就必须处理这个对象
throw关键字后边创建的是RuntimeException或者是Exception的子类对象,我们可以不处理,默认交给JVM处理。
throw后边创建的是编译期异常(写代码的时候)我们就必须处理这个异常,要么throws 要么try。。。。catch。。。。
public static<T> T requireNoNull(T obj):查看指定对象是否为空。
throw是抛异常的意思,它是new一个对象自己来抛。
throws 让JVM来帮我们抛异常。 作用:当方法内部抛出异常对象的时候,我们就必须来处理这个异常对象。可以使用throws关键字来处理对象,会把异常对象声明抛出给方法的调用者处理。最终交给JVM处理。
注意:1、throws关键字必须再方法的声明处
2、throws关键字后边必须是Exception后者是exception的子类。
3、方法内部抛出了多个对象,那么throws后边也必须声明多个异常对象,如果抛出的多个对象有子父类关系,那么直接声明父类即可
4、调用了一个声明抛出异常的方法,我们就必须处理这个异常,要么继续throws声明抛出,要么用try。。。catch。。
若果是编译期异常 再throw异常的时候必须在声明方法的时候throws, 如果是运行期异常那么在声明方法的时候不用throws
try catch 的使用格式
try{
可能才生异常的代码
}catch(定义一个异常变量,用来接受try中抛出的异常对象){
异常的处理逻辑,产生异常对象后,怎么处理异常对象
一般在工作中,会把异常的信息记录到一个日志中。
}
1、try中可能抛出多个异常对象,那么就可以使用多个catch来处理
2、如果try中没有产生异常,那就不会执行catch中的异常处理逻辑,执行try中的代码后继续执行try。。catch后的代码
3、当一个try多个catch的时候 如果多个catch中的存在子父类关系的话,那么子类的catch要写在上边,否则的话就会报错。 F
finally代码块:
finally中的东西无论如何都会执行。
注意事项:
1、finally不能单独使用,必须和try一起使用。
2.finally一般用于资源释放(资源回收),无论程序是否出现异常最后都会资源释放(IO)。
线程的调度分为:抢占式调度和分时调度。
多线程的实现步骤:
1、先创建一个继承Thread的类
2、在新建的类中重写run方法
3、创建Tread类的子类对象
4、调用Tread类中的start方法,开启新的线程,执行run方法。
多线程再内存中的执行方法:
在main方法中创建一个继承了Thread的类的对象并且用这个对象调用start方法的时候 我们会在栈内存中开辟一块和main方法一样的空间。cpu会在main方法和这个新空间中的程序中随机切换随机执行。
多线程的好处:多个线程互不影响(在不同的栈空间中)
Thread类中的一些常用的方法:
获取线程的名称有两种方法:1、String getName()返回线程的名称。
2、可以通过获取当执行的线程,使用线程中的方法getName()获取线程的名称。static Thread currentThread()返回当前线程的引用。
设置线程的名字:
1、使用Thread中的setName() 方法
2、创建一个带参数的构造参数,参数传递线程名称,然后将这个名称传给它的父类Thread,让父亲来给他起名字。
其中的sleep方法,他是一个静态方法,直接用Thread类去调这个sleep方法就可以了。
创建一个新线程的第二种方法:实现Runnable接口的方式。
实现步骤:
1、创建一个Runnable接口的实现类
2、在实现类中重写run 方法,设置线程任务
3、创建一个Runnable接口实现类的对象
5、创建一个Thread类对象,构造方法中传入Runnable接口实现类对象
4、用Thread对象调用start()方法。
继承Thread和Runnable的区别:
1、避免了单继承的局限性
因为一个类只能继承一个类,如果继承了Thread类就不能再去继承其他的类了,用实现Runnable接口的,就还可以去继承其他的类,也可以实现其他的接口
2、增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnable接口的方法,将任务和开启线程分开了。我们可以创建多个Runnable接口的实现类,并且在不同的实现类中存不同的任务,在我们开启线程的时候要做哪个任务我们就传入什么Runnable实现类,将开启线程和实现任务分开。
多线程的安全问题:
程序到最后出现了重复的票和不存在票,原因是:几个线程同时进入了if
同步代码块解决线程安全问题:
synchronized(锁对象){可能出现线程安全问题的代码}
注意:1、通过代码块中的锁对象,可以使用任意的对象
2、但必须保证多个线程使用的代码是同一个
3、锁对像的作用
把同步代码块锁住,只让一个线程同步进行代码块中的东西
解决线程安全问题的第二种方法:同步方法。 就是在声明方法的时候用synchornized
但是这种方法没有同步代码块的效率高.
解决线程安全问题的第三种方法:使用Lock锁
使用步骤:1、首先在成员位置创建一个ReentraLock
2、在可能出现安全问题的地方调用Lock接口中的方法lock获取权限
3、使用完成之后在解锁 unlock。
等待唤醒,也就是线程之间的通信。
使用 wait和notify方法 |
|