java常用对象

本文深入讲解Java集合框架的基础概念及其实现方式,包括List、Set、Map的不同应用场景和特点,以及多线程环境下集合的使用注意事项。

boolean b=Pattern.matches("(86)*0*1\\d{10}",mobile);//大陆手机号码的匹配

日期类
Date date =new Date();//构造当前的时间
calendar=Calendar.getInstance();//通过工厂方法获取实例
calendar.set(year, month, date);//设置年月(0-11)日 时分秒位当前时间
calendar.set(year, month, date, hourOfDay, minute, second);//设置年月日时分秒
DateFormat df=new SimpleDateFormat("yyyy年MM月dd日 HH点mm分ss秒");
String s=df.format(date);
Date date=df.parse(date_str);

在多线程的情况下使用StringBuffer 保证数据的同步。在单线程情况下两个都可以用StringBuilder会快一些。

集合:长度可以自动的扩展,存储的类型可以不限定(这点不太安全)
JAVA的集合框架中有两个基本的集合接口,一个是Collection,还一个是Map
Collection接口有比较实用的实现方式:有序列表list 无序列表Set 和队列Queue
List:有序列表,存储空间是有下标的,可以按位置存取
Set:散列集合,存储空间没有下标
前两者都是Collection的子接口
Map:键值对,根据键值K取V,键值K是唯一的

优势:增强for循环能不需要定义下标i,简洁方便,无序的集合页可以读取
由于增强循环比较简洁,不需要按位置读取,所以不知道当前元素的位置

JAVA的集合是可以存储多个数据类型的,Collection coll=new ArrayList();在coll中可以存储除了基本数据类型(装箱为包装类存储)的一切对象。就是说可以存储Integer String Employee所以在读取的时候是无法知道其准确的类型是什么的?
需要强制类型转换,除非事先知道类型否则会出现类型转换异常,这样程序的安全性就降低。
使用泛型,就是在编译阶段限定其存储的类型是什么,这样就不能随便存储其他类型了,读取时也不需要强制类型转换了。

集合中使用泛型来指定参数类型:
1.可以让代码更安全健壮
2.不需使用强制类型转换

集合的迭代器——操作元素
Iterator迭代器有三个操作方法:
hasNext():如果仍有元素可以迭代,则返回true.
next():返回迭代的下一个元素
remove():从迭代器指向的collection中移除迭代器返回的最后一个元素
注意在读取前一定要进行判断是否可以迭代(hasNext()),然后进行读取下一个(next())
集合接口方法获取出迭代器:注意import相关接口
Iterator iterator=arr.iterator();

集合的使用起来容量可以扩展,而且有很丰富的API所以在使用时,比数组多得多,之后的学习和工作中都会使用集合进行存储数据:
1.  集合长度自动扩展
2. 集合可以使用泛型指定存储类型,必须是引用类型,不能存储基本类型,如:int
3.集合的api比较丰富,比如add,remove,contains方法判断包含元素
4.集合接口有丰富的数据结构实现
PS:包含 比较,删除等需要判断是否同一个对象,都是比较对象的地址,按照值比较需要重写equals和hashCode 方法

有序列表List
集合中最常见的一个集合是有序列表list:
List接口是有序的列表,与父类 Collection比包含了Collection所有的方法,又扩展了能精确地控制每个位置上的元素的方法:
如:
list.get(i);读取第i位置的元素;
add(int index, E element)指定位置添加元素
remove(int index)移除指定位置的元素
set(int index, E element)
subList(int fromIndex, int toIndex)截取子列表
list.size();
list.add();
list.remove();
list.get(i);

ArrayList:数组实现方式,查询速度快,按位增删速度慢
LinkedList:链表的实现方式,按位增删速度快,查询速度慢
Vector:多线程时线程同步的,保证数据安全

无序列表
Set 是一个散列的集合,数据会按照散列值存储的,两个hello的散列值相同,会存储在同一个地址中,所以看到的就是只有一个hello在集合中了
Set的特征是:
不会出现重复的元素(按照equals 和hashCode 的规则比较是否重复)
Set属于Collection的子接口,拥有Collection的所有的方法
Set 是散列存储没有位置编号,没有按照编号进行操作的方法

Set接口也有不同的实现方式:
HashSet:散列集合里存储的对象必须正确重写hashCode和equals方法
TreeSet:树集集合通过二叉树算法保证无重复元素,并对元素进行排序(自然顺序)
要求要存储的类要实现Comparable接口,重写compareTo方法(后续会将排序的接口)

Map映射容器
Map(映射)是一个可以根据键值进行存储的,它的一个 Key 对应的是一个存储的位置,所以Key值是唯一的,根据Key值可以获取到对应的存储的Value
这种存储的集合我们称为 “键-值” Map
1. 它不是集合Collection的子类;
2. 它的键值是唯一的,根据键值可以取出值
3. 根据值无法直接取出Key
//存储操作:
map.put("key1","value1");
map.put("key2","value1");//value值是可以重复的
//读取操作
map.get("key1");
是否包含K map.containsKey(Object key)
是否包含V map.containsValue(Object value)
取出所有的K值 Set<K> map.keySet() 返回的是K的Set
取出所有的Value Collection<V> map.values()  返回的是K的是Collection

Map的几种实现方式
同样的对于Map接口是有多种实现方式的
HashMap 按照散列存储,这样的存取较快,线程不安全的,允许存放null键,null值
Hashtable 线程安全,速度慢,不允许存放null键,null值
TreeMap 键值使用二叉树来保证唯一的对键值有排序功能

Map和Set还有List一样如果涉及到包含,比较等操作,自定义的对象需要正确重写equals 和hashCode方法才能满足我们想要的结果
Map的键值可以用Employee,Map<Employee,Integer> Employee需正确实现equals和HashCode
Set中存储Employee Employee需正确实现equals和HashCode
List中包含操作contains 等都是需要实现实现equals和HashCode

Collections
常用的方法:
sort(List<T> list):将集合List的进行按照升序进行排序
binarySearch(List<? extends Comparable<? super T>> list, T key)二分查找Lisi中的元素
copy(List<? super T> dest, List<? extends T> src):将src 中的数据复制到dest中
max(Collection<? extends T> coll):获取集合中最大的元素
min(Collection<? extends T> coll):获取集合中最小的元素
reverse(List<?> list)将List进行反转


使用Collections.sort();排序能够排序Integer String等类型,却无法对我们自己定义的员工类进行排序????
public class Car implements Comparable<Car>{
    public int compareTo(Employee o) {
       return (this.getWeight().compareTo(o.getWeight()));
    }
}

排序的方法有两种:
sort(List<T> list) 根据元素的自然顺序 对指定列表按升序进行排序。
sort(List<T> list, Comparator<? super T> c) 根据指定比较器产生的顺序对指定列表进行排序
两种啥区别的呢:
第一种自身支持排序功能,实现了排序Comparable接口的可以直接按照默认规则排序
第二种按照比较规则排序,有没有实现接口无所谓,因为有比较器
比如,员工默认支持按照编号排序,现在实现功能
第一步:按照编号排序
第二步:按照工资排序
一个排序接口如何支持两种呢?
比较器接口就不一样了,它不需要再本类上实现,可以编写多个实现类
如汽车比较器可以这样写
按照重量的比较器
public class CarSpeedComparator implements Comparator{
  @Override
  public int compare(Car car1, Car car2) {
    return (car1.getSpeed()-car2.getSpeed());
  }
}
按照速度的比较器
public class CarWeightComparator implements Comparator{
  @Override
  public int compare(Car car1, Car car2) {
    return (car1.getWeight()-car2.getWeight());
  }
}
比较时可以根据场景不同指定不同的比较器
sort(list, speedComparator) 或者sort(list,weightComparator)


多线程:
利:
多线程可以提高程序运行效率和资源的利用率。
弊:
多线程会比较消耗资源,效率比较低。处理不好的话会造成线程死锁。

多线程的实现方法
在Java中实现线程有两种方式:
1.继承Thread类
从Thread类中实例化的对象即代表线程,启动一个线程就是建立一个Thread实例。因为完成线程真正功能的代码放在类的run()方法中,所以可以将线程要做的事写在run()方法中即可。然后调用Thread类中的start()方法执行线程,也就是调用run()方法。
2.实现Runnable接口
Java不支持多重继承,因此如果有一个子类要想实现线程,那就可以实现Runnable接口。实现了Runnable接口并编写run()方法,使该任务可执行你的命令。
一般推荐大家实现Runnable接口来实现多线程。

线程通信常用方法
sleep();----强制正在执行的线程休眠(暂停执行),单位是毫秒(不释放资源)。
注意:线程睡眠到期自动苏醒,并返回到可运行的状态。sleep()中指定的时间使线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
wait();当前线程暂停,等待notify()来唤醒(释放资源)。
join();当前线程暂停,等待加入的线程运行结束,当前线程继续执行。
使用锁对象的notify()方法可以将正在等待的线程唤醒,但是同时有多个线程都处于等待状态,notify()只是随机唤醒一个。
我们可使用notifyAll()方法,唤醒所有的等待的线程。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值