java复习4

多线程
进程–正在执行的程序,代表应用程序的执行区域
线程–进程的执行路径,进程中一个负责程序执行的控制单元
jvm启动至少有两个线程
主线程和垃圾回收线程
start & run
调用start方法后,线程处于就绪状态,此时线程对象仅有执行资格,没有执行权
当线程抢到执行权时,调用run方法,当run方法执行完毕,线程死亡,不能复生
线程随机性
同一时刻,CPU只能执行一个线程,这个多线程其实是CPU高速切换造成的
使用多线程
当许多对象需要对同一有限资源进行操作的时候,使用多线程
线程状态内容,每一个状态的特点
创建线程对象后,并对这个对象进行了一些初始化工作
当调用start方法,这个对象就有执行资格,没有执行权,处于就绪状态
当抢到执行权后进入运行状态,这个对象既有了执行资格,又有执行权,
–当调用run方法,此线程进入死亡状态
–当调用stop方法,令其强制死亡
–在运行状态,调用sleep方法或者wait方法,进入阻塞状态,此时,对象释放执行资
格和执行权
–当sleep或者wait方法时间结束后,亦或者调用nofity / notifyAll方法,该线程被唤醒
进入就绪状态
创建线程
继承Thread
重写run()方法,里面是要运行的代码
创建对象,调用start()方法,执行run()方法
线程生命周期----创建 阻塞 运行 死亡
实现Runnable
重写run()方法,里面是要执行的代码
创建Thread对象,传入实现Runnable的类,调用start()方法,执行run()方法
两种方法比较
实现Runnable接口,单独封装了线程任务,避免了继承的局限性
继承Thread类,不能共享资源(任务)
多线程的安全
原因----线程访问的延迟,线程的随机性
解决----加锁,使操作同步,保证数据的一致性
同步
同步代码块
+
同步方法
+
死锁
+
线程间的通信
多个操作,多线程,对某个资源操作
应用(等待唤醒机制)
共享数据–>出现线程安全问题–>使用同步代码块–>完成线程间的通信–>等待唤醒机

public class Student{
private String name;
private int age;
private boolean flag;
}
public class Input implements Runnable{
privat Student s;
//有参构造
Input(Student s){
this.s = s ;
}
public void run (){
int x = 0;
while(true){
synchronized(s){
if(s.flag){
try{
s.wait( ) ;
} catch(Exception e) { e.printStackTrace(); }
}
if( x == 0 ) {
s.name = “aa”;
s.age = 20;
}else {
s.name = “bb”;
s.age = 20;
}
s.flag = true;
s.notify( ) ;
x = ( x + 1 ) % 2 ;
}
}
}
}
public class Output implements Runnable{
private Student s ;
Outut(Student s ) {
this.s = s;
}
public void run( ) {
while( true ) {
syncronized(s) {
if(!s.flag){
try{ s.wait( ) ; } catch(Exception e ){e.printStackTrace(); }
}
System.out.println(s.name +" “+s.age );
s.flag = false ;
s.notify();
}
}
}
}
wait() & notify() & sleep
wait() notify() notifyAll() 都定义在Object类中
这些方法存在与同步中
使用这些方法时必须要标识所属的同步到锁
锁可以是任意对象,所以任意对象调用的方法一定定义在Object中
wait() sleep()
对时间指定而言
wait() 可以不指定时间
sleep() 必须指定时间
对执行权和锁而言
wait() 释放CPU执行权和资格,释放锁,存储于线程池
sleep() 释放CPU执行权,不释放锁
停止线程
通过控制循环
interrupt()方法
stop()已过时,被interrupt()取代
守护线程 后台线程
设置一个线程为守护线程,当主线程结束,守护线程结束
setDaemon(boolean flag )
join() 加入线程,抢夺执行权,自己执行完毕,其他线程才有机会执行
toString() 线程名称,优先级,线程组(多个线程组成,默认线程组时main)
yield() 暂停自己,执行权交给其他线程
setPriority( int num) 设置线程优先级
getPriority() 获取线程优先级
线程优先级别1–10 默认级别 5
生产者和消费者
class Resource {
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name ) {
//当线程每次醒后再判断一次
while(flag){
try{ this.wait(); } catch(InterruptedException e){”"}
this.name = name + count ;
count ++ ;
System.out.println(Thread.currentThread().getName() + “…生产者…” + this.name);
flag = true ;
motifyAll();
}
}
public synchronized void out(){
while( ! flag ){
try{ thiss.wait(); } catch(InterruptException e){""}
System.out.println(Thread.currentThread().getName() + “…消费者…” + this.name);
flag = false ;notifyAll();
}
}
}
class Shengchan implements Runnable{
Resource r ;
Shengchan(Resource r){
this.r = r;
}
public void run(){
while(true) r.set(“烤鸭”);
}
}
public Xiaofei implements Runnable{
Resource r ;
Xiaofei (Resource r){
this .r = r ;
}
public void run(){
while(true) r.out() ;
}
}
public class ThreadTest{
public stativ void main(String[] args){
Resource r = new Resource();
Shengchan sc = bew Shengchan();
Xiaofei xf = new Xiaofei();
Thread t1 = new Thread(sc);
Thread t2= new Thread(sc);
Thread t3= new Thread(sc);
Thread t4= new Thread(xf);
Thread t5 = new Thread(xf);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();

			}
		}
Lock & Condition接口
	JDK1.5之后,同步和锁封装成了对象,操作锁的隐式方式定义到了对象中,变成了显示锁操作
	替代了同步代码块和同步方法,更为灵活,可以一个锁加上多个监视器
	java.util.concurrent.locks.Lock接口,提供了lock()  unlock()(unlock()通常定义在finally代码块中)
	对于释放和获取锁,都是隐式的
	Lock lock 
	public void run(){
		try{ lock.lock() ;}
		finally { lock.unlock() ;}
	}
	Lock接口替代了synchronized
	Condition替代了Object类中监视器方法 wait()  notify()  notifyAll()
	将监视器方法单独封装成了Condition对象,而且一个锁上可以组合多个监视器对象
	await()  signal()  signalAll()唤醒
	可与任意锁组合
Scanner类
	Scanner sc = new Scanner(System.in);

String
字符串数据都是一个对象;
字符串数据一旦初始化就不可以被改变
字符串数据存储于常量池中,字符串常量池
String s1 = “abc”;
String s2 = “abc”;
s1 == s2 ; //true
常量池中已经存在"abc",不会再开辟新空间,直接指向已经存在的"abc"
String s3 = new String(s1);
s1 == s3; //false
new 重新开辟的内存空间
s1.equals(s3); //true
String 类重写了Object类中的equals()方法,比较的是字符串中的内容是否相同
判断
equals(Object obj) 比较字符串的值是否相等
equalsIgnoreCase(String anotherString) 不区分大小写,字符串值是否相等
contains(String s) 是否包含
startsWith(String prefix) 是否以指定前缀开始
startsWith(String prefix,String toffet) 从制定索引开始的字符串是否以指定前缀开始
endsWith(String suffix) 是否以制定后缀结束
isEmty() 是否为空
获取
int length() 获取字符串的长度
char charAt(int index)获取指定位置的字符
String s = “HelloWorld”;
//char[] ch = s.toCharArray();
char[] ch = new char[s.length()];
for(int x = 0 ; x < s.length() ; x++) {char[x] = s.charAt(x); }
int indexOf(int ch) 获取指定字符在给定字符串中第一次出现的索引
int indexOf(int ch,int fromIndex) 返回此字符串中第一次出现指定字符的索引,从指定的
字符开始
int indexOf(String str)
int indexOf(String str,int fromIndex)
int lastIndexOf(int ch)
int lastIndexOf(int ch,int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str,int fromIndex)
String subString(int beginIndex)返回一个新的字符串,是此字符串中的一个子字符串
String subString(int beginIndex,int endIndex)返回一个新字符串,是子字符串,含头不含

转换
字符串于字节数组之间
String --> byte[] ------byte[] getBytes();
byte[] --> String ------new String(byte[] by);//构造方法
字符串 字符数组 之间
String --> char[] -------char[] toCharArray();
char[] --> String -------new String(char[] ch)
static copyValueOf(char[] data)
static String valueOf(char[] data,int offset ,int count)
static String valueOf(xxx x)//xxx基本数据类型
static String valueOf(Object obj) //把对象转换成字符串
String toUpperCase() 所有字符都转换成大写
String toLowerCase() 所有字符都转换成小写
String concat(String str) 将指定字符串连接到此字符串结尾
s.concat(“aaa”).concat(“bbb”)
替换
String replace(char oldChar.char newChar)返回替换后的新字符串
String replace(String oldString,String newString)
切割
String[] split(String regex)
去除空格
trim()
按字典顺序比较两个字符串
int compareTo(String anotherString)
统计字符串中大写字母 小写字母 数字的个数
public static int[] getCount(String str){
int upper_count = 0;
int lower_count = ;
int num_count = 0;
int[] arr = new int[3];
char[] chs = str.toCharArray();
for(char ch : chs){
if(ch > 64 && c < 97){
lower_count++;
}else if(ch > 96 && c < 123){
upper_count++;
}else if(ch > 47 && ch < 58){
num_count++;
}
}
arr[0] = lower_count;
arr[1] = upper_count;
arr[2] = num_count;
}
字符串数组自然排序
//互换位置
public static void swap(String[] str , int i , int j ){
String temp = str[i];
str[i] = str[j];
str[j] = temp;
}
//打印数组
public static void printArray(String[] str){
StringBuilder sb = new StringBuilder();
sb.append(" {" “);
for(int i = 0 ; i < str.length ; i++ ){
if( ! ( i = str.length - 1) ){
sb.append(str[i] + " “,” “);
}else{
sb.apend(str[i] + " “} “);
}
}
System.out.println(sb);
}
//排序
public static void sort(String[] str){
for(int i = 0 ; i < str.length - 1 ; i++ ){
for(int j = 0; j, str.length ; j++){
if(str[i].compareTo(str[j]) > 0 ){
swap(str,i,j);
}
}
}
printArray(str);
}
查找子串在大串中出现的次数
public static int getCount(String big,String small){
int count = 0;
int index = 0;
while( (index = big.indexOf(small , index)) != -1 ){
//indexOf()从指定的index开始搜索,index是新的搜索起点
index = index + small.length();
count++;
}
return count;
}
查找两个字符串中最大的两个子串(正三角)
+
对字符串中的数据进行排序
+
StringBuffer & StringBuilder
String定长 StringBuffer变长
append(元素)追加
insert(索引 , 元素 )
reverse() 反转
capacity() 容量 可以存储的个数
length() 长度 实际存储的元素个数
StringBuffer 线程安全,效率低 同步
StringBuilder 线程不安全 效率高 不同步
封装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean boolean
自动拆装箱
Integer i = new Integer(5);
Integer ii = 6; //自动装箱
Interger iii = ii + 7; //ii拆箱成int ,加7 ,装箱Integer
ii.intValue();
基本类型转换成字符串
static String toString(int x);
字符串到基本类型的转换
static int parseInt(String str);
static Integer valueOf(String str);
他们都实现了Comparable接口,具备compareTo方法,用于比较
结果只有整数,正数, 负数
基本类型数据用比较运算符进行比较,引用数据类型用compareTo进行比较
集合框架
集合长度可变,不能存储基本数据类型,只能存储对象
数组长度固定,可以存储基本数据类型,可以存储对象
体系
Collection
List
ArrayList
Vector
LinkedList
Set
HashSet
TreeSet
collection接口
添加
Boolean add(E e);
Boolean addAll(Collection<? ectends E> e);
删除
Boolean remove(Object obj);
Boolean removaAll()Collection con;
void clear();删除所有
判断
Boolean contains(Object obj);
Boolean containsAll(Collection con);
Boolean isEmty();
获取
int size(); 集合大小 数组大小:length 字符串大小:length();
Iterator iterator();
. . . . . .
迭代要强转,只能有一个next()方法,否则NoSuchElementException
交集
Boolean retainAll(Collection con); 调用者内容被两者交集覆盖,发生变化,返回true
否则返回false
集合转数组
Object[] toArray(); 集合转换成对象
List接口
有序(存入和取出顺序一致),院元素都有索引(角标),元素可以重复
操作角标,完成对元素的增删改查
凡是有索引的容器,都有增删改查的方法
添加
void add(index .element);
void add(index,collection);
删除
Object remove(index);
修改
Object set(index,element);
获取
Object get(index);
int subList(startIndex, endIndex);获取子列表
int indexOf(obj); 返回对象所在的位置
int lastIndexOf(obj);返回对象最后出现的位置
ListIterator:拥有对元素进行增删改查的方法----List特有
List接口的子类
Vector :内部是数组数据结构 线程安全 增删改查慢
ArrayList:内部是数组数据结构 不同步 代替Vector 查询快
内存原理
在ArrayList集合中,是一种线性表,有序存储每个对象,用角标确定对象存储的
位置,查询时,对角标进行查询,所以快,增删改要影响后面对象的角标,所以

LinkedList:内部是链表数据结构 不同步 增删改快
内存原理
每个对象都存储下一个对象地址,,查询时,逐个访问,所以慢
增删改时,对地址进行操作,提高了运行效率
Set接口
不可重复 无序 方法与Collection的方法一样
HashSet
内部结构是哈希表 不同步
哈希表相当于角标,查询时,直接根据哈希值查询,速度快
判断两个哈希值是否相同,使用hashCode()方法,如果相同,在判断两个对象的
内容是否相同,使用equals()方法
----如果元素要存储到hashSet集合中,必须覆盖hashCode() 和 equals()
TreeSet
可以对元素进行排序, 不同步
判断元素是否唯一:比较方法返回结果是0,就是相同元素,不进行存储
按自然顺序排序
让元素自身具备比较功能,需要实现Comparable接口,覆盖compareTo()方法
自定义排序
定义一个类,实现Comparable接口,覆盖compareTo()方法,将该类作为传递
参数传递给TreeSet集合的构造方法
Tips
同步与不同步
后缀是集合名称xxxList ,xxxSet 是同步
后缀没有,如Vector 是同步的
数据结构
前缀是数据结构,后缀是所属体系
需要唯一,用Set
顺序,用TreeSet
不需要唯一,用List
侧重增删改,用LinkedList
泛型
JDK1.5之后出现的安全机制,解决类型安全问题,只能用于编译时期,提高安全性
好处
将运行时期的问题ClassCastException,转移到编译时期
避免强制类型转换的麻烦
使用
当操作的引用数据类型不确定时
< >在类上或者接口上,给编译器使用
运行时,会将"泛型擦除”,因为要兼容运行的类加载器
泛型的补偿
当方法静态时,不能访问类上的定义的泛型,只能将泛型定义在方法上,–写在方
法的返回值前面
泛型接口
泛型通配符:<? 未知类型>
泛型的限定
?extneds E --接收E类型或者E类型的子类对象 上限
一般在存储元素时用上限,因为这样取出都是按照上上限类型运算的,不会出现
类型安全隐患
? super E --接收E类型或者E的父类对象 下限
通常对集合的元素进行取出操作时,用下限
Map
一次添加一对元素 ,Collection一次添加一个元素
双列集合 ,Collection单列集合
存储的时说键值对
必须保证键的唯一性
方法
添加
value put(key,value);
删除
void clear();清空
value remove(key); 根据指定的键删除这个键值对
判断
Boolean containsKey(key);
Boolean containsValue(value);
Boolean isEmpty();
获取
value get(key);
int size();获取键值对的大小
遍历
public void show(){
Map<Student,String> map = new HashMap<>();
map.put(new Student(“李磊”,23) , “河北” );
. . . . . .
for(Integer in : map.keySet(){
System.out.println(map.get(in));
}
for (Entry<Student,String> entry : map.entrySet() ) {
Student s = entry.getKey();
String str =map.get(entry.getKsy() );
System.out.println(s.getName() + “\t” + s.getAge() + “\t” + str);
}
}
子类
HashTable 内部结构哈希表 同步 不允许null作键 ,null可以作值
Properties 用来存储键值对类型的配置信息 可以与IO技术相结合
HashMap 内部结构哈希表 不同步 允许null值作键
TreeMap 内部构造二叉树 不同步 可可以对map集合进行排序
给非同步集合加锁
List list = new ArrayList();
list = MyCollection.synchronizedList ( list );
class Mycollection {
public List static synchronizedList(List list){
return new MyList(list);
}
}
class Mylist implements List{
private List list ;
private static final Object lock = new Object();
MyList(List list){
this.list = list;
}
public Boolean add(Object obj){
Synchronized(lock){
return list.add(obj);
}
}
public Boolean remove(Object obj){
Synchronized(lock){
return list .remove(obj);
}
}
}
Map & Collection
Collection 单列 一组单个对象 Map 双列 一组键 一组值
Collection.add(); Map.put();
Collection直接使用迭代器 Map集合转换成Set集合,再用迭代器去取出元素
Map练习
public static void getCount(String str){
char[] chs = str.toCharArray();
TreeMap<Character , Integer> tm = new TreeMap<>();
for(char ch : chs){
if( ! (c >= ‘a’ && c <= ‘z’ || c >= ‘A’ && c <= ‘Z’) ){
continue ; }
int count = 1;
//c不为null,递增,为null,put
Integer value = tm.get©;
if(value != null){
count = ++value;
}
tm.put(c , count );
}
StringBuilder sb = new StringBuilder();
for(char c : tm.keySet()){
sb.append©.append(”(”).append( tm.get©.append(”)") );
}
return sb.toString();
}
Collections中常见方法
static<T extends Comparable<? super T>> void sort(List list);
将集合进行排序,并可以指定集合参数的类型,要继承Comparable接口
static void swap(List<?> list , int i ,int j ); 根据指定位置交换集合中的元素
static void shuffle(List<?> list); 对集合中元素位置随机发生变化
static int binarySearch( List<? extends Comparable<? super T>> list,);
使用二分查找给出指定的值在集合中的位置
static List synchronizedList(List list);
Collection & Collections
Collection
所有单列集合的父接口,以一组单个对象存储
. . . . . .
Collections
对集合操作的一个工具类, 方法都是静态 可以对集合进行排序 交换位置 二分查
找 元素顺序随机变化等等
arrays常见方法
static List asList(T. . . a); 将数组转换成List集合
static int binarySearch(int[] a,int key); 使用二叉树查找法查找指定元素在数组中的位置
static int[] copyOf(int[] original, int newLength); 指定数组长度并复制到其他数组
static int[] copyOfRange(int[] original,int from,int to); 复制指定的范围
static boolean equals(int[] a,int[] b); 判断两个数组是否相等
static void fill(int[] a,int val); 将数组中的值变为指定的值,相当于初始化值
static int hashCode(int[] a) ; 返回数组的哈希值
static void sort(int[] a, int fromIndex,int toIndex);指定数组范围并进行排序
static String toString(int[] a); 将数组转换成字符串
static boolean deepEquals(Object[] a ,Object[] b);判断两个对象的深度是否相等
数组《==》 集合
数组转集合
可以对数组中的元素通过集合中的方法进行操作,只要不影响长度,几乎所有的方
法都可以使用
集合转数组
为了限制集合中元素操作,它只有一个length属性可以操作
—whatever which transfer to another ,length can not be changed , 增删 are forbidden
增强for & 普通for
普通for可以对循环条件进行控制
增强for只能简化书写,遍历集合和数组中的元素
forEach不可以直接遍历Map集合,需要先把Map转成Set,再根据Set集合迭代出元素
使用Map时机
发现存在映射关系,可以考虑使用 数组 和 Map
可变参数
int add(T. . . a);可以添加多个不同类型的数据,等同于传入数组形式的参数
int add(T a,T . . . a1); 除了第一个为a,其他全部是可变参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值