黑马程序员技术交流社区
标题: 2019/03/30复习资料 [打印本页]
作者: 风一般d逍遥 时间: 2019-3-30 13:06
标题: 2019/03/30复习资料
Collection集合特点(1)
1).Collection是集合类的根接口,Java中没有提供这个接口的直接的实现类。但有继承该类的两大接口类,就是List和 set集合,set集合不能包含重复的元素,List集合是一个有序的集合,可以包含重复的元素。
2)Map集合Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。和 collection集合最大的区别就是,Map集合是双列的,一般是成对出现的,即(键,值)总是以键值对出现。
风一般的逍遥:
3.java中的单列结合
java单列结合的家族中,collection是根接口,其下有两个继承子类List和Set集合。
List又有ArrayList,vector,LinkedList三个子类 Set有Hashset和Treeset两个子类
3.1 单列各个集合底层数据结构和基本性质
一.List集合:(有序,元素可以重复)
1.ArrayList集合:
1).底层数据结构是数组,查找快,增删慢。
2). 线程不安全,效率高
2.Vector集合:
1) 底层数据结构是数组,查询快,增删慢
2)线程安全,效率低
3.LinkedList集合:
1) 底层数据结构是链表,查询慢,增删快
2)线程不安全,效率高
风一般的逍遥:
二、Set集合(元素不可重复,元素唯一)
1.Hashset集合:
1) 底层数据结构是哈希表,哈希表依赖两个方法hascode ()和equals()方法
2)两个方法的执行顺序:
首先判断hascode()值是否相同
是:继续执行equals()方法,看其返回值
是true:说明元素重复,不添加
是false:就直接添加元素
否:就直接添加到集合
2.Treeset集合:
1)底层数据结构是二叉树
风一般的逍遥:
4.java的双列集合
1. java中的Map集合是双列的,Map集合是Map集合家族的根接口,它有HashMap和TreeMap集合两个子类。
2. Map集合中只对键有效,而对值是无效的。
3.子类的数据结构:
Hashmap:底层数据结构是哈希表,Treemap底层数据结构是二叉树,其性质和Set的底层数据结构一样。
计算出生到现在过了多少天(2)
package com.itheima.demo01;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class TestBirthday {
public static void main(String[]args) throws ParseException {
SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd");
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的生日:");
String birthday = sc.next();
Date bd = sdf.parse(birthday);
long time1 = bd.getTime();
Date now = new Date();
long time2 = now.getTime();
System.out.println("您的生存时长为:" + ((time2 - time1) / 1000 / 60 /60 / 24) + "天");
}
}
集合(3)
ackage com.itheima.demo02;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
给定以下代码,请定义方法publicstatic int listTest(Collection<String> list,String s)统计集合中指定元素出现的次数,如"a":2,"b":2,"c" :1, "xxx":0。
Collection<String> list =new ArrayList<>();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
System.out.println("a:"+listTest(list,"a"));
System.out.println("b:"+listTest(list,"b"));
System.out.println("c:"+listTest(list,"c"));
System.out.println("xxx:"+listTest(list,"xxx"));
*/
@SuppressWarnings("all")
public class Day02Test01 {
public static void main(String[]args) {
Collection<String> list =new ArrayList<>();
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("c");
System.out.println("a:"+listTest(list, "a"));
System.out.println("b:"+listTest(list, "b"));
System.out.println("c:"+listTest(list, "c"));
System.out.println("xxx:"+listTest(list, "xxx"));
}
public static intlistTest(Collection<String> list,String s){
int a = 0;
Iterator<String> it =list.iterator();
while(it.hasNext()){
String n = it.next();
if (n.equals(s)){
a++;
}
}
return a;
}
}
**String类中的常用方法(4)
(1)booleanisEmpty(): 判断字符串是不是空串,如果是空的就返回true
(2)charcharAt(int index): 返回索引上的字符
(3)StringtoLowerCase(): 字符串转成小写
(4)StringtoUpperCase(): 字符串转成大写
(5)Stringrepalce(char oldChar, char newChar): 将字符串中的老字符,替换为新字符
(6)Stringrepalce(String old, String newstr): 将字符串中的老字符串,替换为新字符串
(7)Stringtrim(): 去掉字符串两端空格
8)public?int?indexOf?(String?str) :返回指定子字符串第一次出现在该字符串内的索引。
(9)public?String?substring?(int?beginIndex,?int?endIndex):返回一个子字符串,从beginIndex到 endIndex截取字符串。含beginIndex,不含endIndex。
1. 编写程序将“jdk” 全部变为大写,并输出到屏幕,截取子串”DK” 并输出到屏幕
2.分析以下需求,并用代码实现:
(1)定义如下方法public static StringgetPropertyGetMethodName(String property);
(2)该方法的参数为String类型,表示用户给定的成员变量的名字,返回值类型为String类型,返回值为成员变量对应的get方法的名字
(3)如:用户调用此方法时给定的参数为"name",该方法的返回值为"getName"
3.分析以下需求,并用代码实现:
(1)定义数字字符串数组{"010","3223","666","7890987","123123"}
(2)判断该数字字符串数组中的数字字符串是否是对称(第一个数字和最后一个数字相等,第二个数字和倒数第二个数字是相等的,依次类推)的,并逐个输出
(3)如:010 是对称的,3223 是对称的,123123 不是对称的
(4)最终打印该数组中对称字符串的个数
提示:循环获取字符串的每一个字符,依次比较第一个和最后一个,第二个和倒数第二个。。。
4.分析以下需求,并用代码实现:
(1)从键盘录入一个字符串
(2)将字符串中大写字母变成小写字母,小写字母变成大写字母,其它字符用"*"代替,并统计字母的个数
举例:
键盘录入:Hello12345World
输出结果:hELLO*****wORLD
总共10个字母
5.分析以下需求,并用代码实现:
(1)定义一个方法
publicObject[] deleteSubString(String str1,String str2) {
}
(2)方法功能描述:从str1中删除所有的str2,并返回删除后的结果,返回结果为Object[]数组
* 该数组的第一个元素为删除所有的str2后的最终的字符串
* 该数组的第二个元素为删除的str2的个数
6. 给定一个字符串,判断该字符串中是否包含某个子串.如果包含,求出子串的所有出现位置.
如:"abcbcbabcb34bcbd"中,"bcb"子串的出现位置为: 1,7,12.字符串和子串均由用户输入
7.给定一个长度,随机产生一个该长度的字符串,由大写,小写字母以及数字组成
Java中随机数的生成:
java.util.Randomr = new java.util.Random();
int a =r.nextInt(100): a 0-99的随机数
synchronized与Lock的区别(5)
两者区别:
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package com.cn.test.thread.lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockTest { private Lock lock = new ReentrantLock(); /* * 使用完毕释放后其他线程才能获取锁 */ public void lockTest(Thread thread) { lock.lock();//获取锁 try { System.out.println("线程"+thread.getName() + "获取当前锁"); //打印当前锁的名称 Thread.sleep(2000);//为看出执行效果,是线程此处休眠2秒 } catch (Exception e) { System.out.println("线程"+thread.getName() + "发生了异常释放锁"); }finally { System.out.println("线程"+thread.getName() + "执行完毕释放锁"); lock.unlock(); //释放锁 } } public static void main(String[] args) { LockTest lockTest = new LockTest(); //声明一个线程 “线程一” Thread thread1 = new Thread(new Runnable() { @Override public void run() { lockTest.lockTest(Thread.currentThread()); } }, "thread1"); //声明一个线程 “线程二” Thread thread2 = new Thread(new Runnable() { @Override public void run() { lockTest.lockTest(Thread.currentThread()); } }, "thread2"); // 启动2个线程 thread2.start(); thread1.start(); } } |
执行结果:
[url=]file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png[/url]
package com.cn.test.thread.lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private Lock lock = newReentrantLock();
/*
* 尝试获取锁 tryLock() 它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false
*/
public void tryLockTest(Thread thread) {
if(lock.tryLock()){ //尝试获取锁
try {
System.out.println("线程"+thread.getName() + "获取当前锁"); //打印当前锁的名称
Thread.sleep(2000);//为看出执行效果,是线程此处休眠2秒
} catch(Exception e) {
System.out.println("线程"+thread.getName() + "发生了异常释放锁");
}finally {
System.out.println("线程"+thread.getName() + "执行完毕释放锁");
lock.unlock(); //释放锁
}
}else{
System.out.println("我是线程"+Thread.currentThread().getName()+"当前锁被别人占用,我无法获取");
}
}
public static void main(String[] args) {
LockTest lockTest = new LockTest();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
lockTest.tryLockTest(Thread.currentThread());
}
}, "thread1");
//声明一个线程 “线程二”
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
lockTest.tryLockTest(Thread.currentThread());
}
}, "thread2");
// 启动2个线程
thread2.start();
thread1.start();
}
}
[url=]file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png[/url]
执行结果:
[url=]file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png[/url]
package com.cn.test.thread.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private Lock lock = newReentrantLock();
public void tryLockParamTest(Thread thread) throws InterruptedException {
if(lock.tryLock(3000,TimeUnit.MILLISECONDS)) { //尝试获取锁 获取不到锁,就等3秒,如果3秒后还是获取不到就返回false
try {
System.out.println("线程"+thread.getName() + "获取当前锁"); //打印当前锁的名称
Thread.sleep(4000);//为看出执行效果,是线程此处休眠2秒
} catch(Exception e) {
System.out.println("线程"+thread.getName() + "发生了异常释放锁");
}finally {
System.out.println("线程"+thread.getName() + "执行完毕释放锁");
lock.unlock(); //释放锁
}
}else{
System.out.println("我是线程"+Thread.currentThread().getName()+"当前锁被别人占用,等待3s后仍无法获取,放弃");
}
}
public static void main(String[] args) {
LockTest lockTest = new LockTest();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
lockTest.tryLockParamTest(Thread.currentThread());
} catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "thread1");
//声明一个线程 “线程二”
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
lockTest.tryLockParamTest(Thread.currentThread());
} catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, "thread2");
// 启动2个线程
thread2.start();
thread1.start();
}
}
[url=]file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png[/url]
执行结果:
因为此时线程1休眠了4秒,线程2等待了3秒还没有获取到就放弃获取锁了,执行结束
将方法中的 Thread.sleep(4000)改为Thread.sleep(2000)执行结果如下:
因为此时线程1休眠了2秒,线程2等待了3秒的期间线程1释放了锁,此时线程2获取到锁,线程2就可以执行了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |