一 、java.util.Collection:(集合层次的根接口)
1、|-- java.util.List : 有序的,并且允许重复的。 List体系的集合具有索引值
①|--ArrayList:(List接口的实现类) 底层数据结构是数组结构。 查询和修改速度快,但是增删慢(具体方法查API),线程不同步,因此效率高
②|--LinkedList: (List接口的实现类)底层数据结构是链表结构。 增添和删除速度快,但是查改慢(具体方法查API)
③|--Vector:采用数组结构存储元素。线程同步,所以效率低(增删改差都慢),淘汰
2、|-- java.util.Set : 无序的,不允许重复的。
①|-- HashSet : 是 Set 接口的典型实现类。底层是hashMap,数据结构是数组加链表(java8加入了红黑树 提高了效率)。
HashSet 判断元素是否存在的依据是(哈希算法),add对象时,先根据对象 hashCode 值判断hashCod对应位置处是否有对象,若此位置hashCode值不存在,则直接存储,若hashCode 值存在,再通过 equals() 比较两个对象内容(因为如果直接只比较equals方法的话,效率会很低 集合中若有十万条就会equals十万次,效率极低,所以根据hashCode直接比较hash表中相应位置是否有元素 若没有 则直接存储 若有 则再比较equals)
注意: hashCode() 方法与 equals() 方法二者需要保持一致!HaseSet 底层是 HashMap HashSet的add()方法添加的是key 而value是final Object值不变
② |-- LinkedHashSet:是 HashSet 的子类,相较于 HashSet 多了链表维护元素的顺序。遍历操作效率高于 HashSet,增删操作效率低于 HashSet
③ |-- TreeSet :(底层采用二叉树的数据结构) 拥有自己的排序方式(能排序String类型和数据类型包装类,若想实现其他自然排序按以下方法)
|--java.lang.Comparable (自然排序):
①需要添加到 TreeSet 集合中的对象的类实现 Comparable 接口
②实现接口中的 compareTo(Object o) 方法
|--java.lang.Comparator (定制排序)(定义一个比较器):
①声明一个类实现 Comparator 接口
②实现接口中的方法 compare(Object o1, Object o2)
③将该实现类的实例,作为参数,传递给 TreeSet 的构造器
public class Student implements Comparable<Student>{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
if(this.age > o.getAge()){
return 1;
}else if(this.age < o.getAge()){
return -1;
}
return 0;
}
}
public class Test {
public static void main(String[] args){
List<Student> list = new ArrayList();
Student st1 = new Student("小明", 1);
Student st2 = new Student("小明", 5);
Student st3 = new Student("小明", 6);
Student st4 = new Student("小明", 3);
Student st5 = new Student("小明", 2);
Student st6 = new Student("小明", 7);
Student st7 = new Student("小明", 8);
list.add(st1);
list.add(st2);
list.add(st3);
list.add(st4);
list.add(st5);
list.add(st6);
list.add(st7);
for(Student student : list){
System.out.println(student);
}
System.out.println("--------------------------------------------------");
Collections.sort(list);
for (Student student : list) {
System.out.println(student);
}
}
}
Student{name='小明', age=1}
Student{name='小明', age=5}
Student{name='小明', age=6}
Student{name='小明', age=3}
Student{name='小明', age=2}
Student{name='小明', age=7}
Student{name='小明', age=8}
--------------------------------------------------
Student{name='小明', age=1}
Student{name='小明', age=2}
Student{name='小明', age=3}
Student{name='小明', age=5}
Student{name='小明', age=6}
Student{name='小明', age=7}
Student{name='小明', age=8}
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args){
List<Student> list = new ArrayList();
Student st1 = new Student("小明", 1);
Student st2 = new Student("小明", 5);
Student st3 = new Student("小明", 6);
Student st4 = new Student("小明", 3);
Student st5 = new Student("小明", 2);
Student st6 = new Student("小明", 7);
Student st7 = new Student("小明", 8);
list.add(st1);
list.add(st2);
list.add(st3);
list.add(st4);
list.add(st5);
list.add(st6);
list.add(st7);
for(Student student : list){
System.out.println(student);
}
System.out.println("--------------------------------------------------");
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge() > o2.getAge()){
return -1;
}else if(o1.getAge() < o2.getAge()){
return 1;
}
return 0;
}
});
for (Student student : list) {
System.out.println(student);
}
}
}
Student{name='小明', age=1}
Student{name='小明', age=5}
Student{name='小明', age=6}
Student{name='小明', age=3}
Student{name='小明', age=2}
Student{name='小明', age=7}
Student{name='小明', age=8}
--------------------------------------------------
Student{name='小明', age=8}
Student{name='小明', age=7}
Student{name='小明', age=6}
Student{name='小明', age=5}
Student{name='小明', age=3}
Student{name='小明', age=2}
Student{name='小明', age=1}
Comparator接口的灵活性
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class AESStudent implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if(o1.getAge() > o2.getAge()){
return 1;
}else if(o1.getAge() < o2.getAge()){
return -1;
}
return 0;
}
}
public class DESCStudent implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if (o1.getAge() > o2.getAge()) {
return -1;
} else if (o1.getAge() < o2.getAge()) {
return 1;
}
return 0;
}
}
public class Test {
public static void main(String[] args){
List<Student> list = new ArrayList();
Student st1 = new Student("小明", 1);
Student st2 = new Student("小明", 5);
Student st3 = new Student("小明", 6);
Student st4 = new Student("小明", 3);
Student st5 = new Student("小明", 2);
Student st6 = new Student("小明", 7);
Student st7 = new Student("小明", 8);
list.add(st1);
list.add(st2);
list.add(st3);
list.add(st4);
list.add(st5);
list.add(st6);
list.add(st7);
Collections.sort(list,new AESStudent());
for (Student student : list) {
System.out.println(student);
}
System.out.println("--------------------------------------------------");
Collections.sort(list, new DESCStudent());
for (Student student : list) {
System.out.println(student);
}
}
}
Student{name='小明', age=1}
Student{name='小明', age=2}
Student{name='小明', age=3}
Student{name='小明', age=5}
Student{name='小明', age=6}
Student{name='小明', age=7}
Student{name='小明', age=8}
--------------------------------------------------
Student{name='小明', age=8}
Student{name='小明', age=7}
Student{name='小明', age=6}
Student{name='小明', age=5}
Student{name='小明', age=3}
Student{name='小明', age=2}
Student{name='小明', age=1}
/**
* 对集合按时间降序排序
*
* @param poList
*/
private void sort(List<ApplyPay> poList) {
Collections.sort(poList, new Comparator<ApplyPay>() {
@Override
public int compare(ApplyPay o1, ApplyPay o2) {
if (o1.getCreateTime().before(o2.getCreateTime()))
return 1;
return -1;
}
});
}
TreeSet判断元素是否相同的依据是compareTo方法或compare方法,只要return 0则两个元素相等,排序时,当主要条件相同时, 一定要判断一下次要条件,否则就会视为同一对象,无法添加到集合,当自然排序和定制排序都存在时,以比较器为主。
二、java.util.Map 接口 : 用于存储成对对象的集合。
具有 key(键)-value(值)对映射关系的集合。一个 key 对应着一个 value, key 不能重复。
|-- HashMap : 是 Map 接口的典型实现类。 是线程不安全的,因此效率高(HashSet判断元素是否相等,底层是用的HashMap的方法)
|-- LinkedHashMap:
|-- Hashtable : 是一个古老的实现。是线程安全的,因此效率低(Hashtable 不允许使用 null 作为 key 和 value)
|-- Properties : 用于操作属性文件(用法见下面代码)
|-- TreeMap : 根据 key 拥有指定的排序方式
|--自然排序(Comparable)
|--定制排序(Comparator)
谈谈你对HashMap中put/get方法的认识?如果了解再谈谈HashMap的扩容机制?默认大小是多少?什么是负载因子?什么是吞吐临界值?
hashMap底层是Entry类型的,名字叫做table的数组,当new一个hsahMap的时候会构造一个容量为16,负载因子为0.75的空hashMap,它的吞吐临界值为16 * 0.75 = 12。当添加达到吞吐临界值的时候会用resize的方法2倍扩容,并且通过transfer()将原来的值放入新的Entry数组中,当执行put命令将key-value键值对放入hashMap中的时候,HashMap在put方法中,它使用hashCode()和equals()方法。当我们调用put方法的时候,HashMap使用Keyd的hashCode()和哈希算法来找出存储key-value对的索引判断位置。如果索引位置处为空,则直接插入到对应的数组中,否则,判断是否是红黑树,若是,则红黑树插入,否则遍历链表,若长度不小于8,则将链表转为红黑树,转成功之后 再插入。
三、用LinkList制作自己的队列
①堆栈排列 先进后出
//堆栈排列,先进后出
public class DuiZhanQueue {
// 将LinkedList封装进对象里
private LinkedList link;
// 公共的get/set方法
public void setLink(LinkedList link) {
this.link = link;
}
public LinkedList getLink() {
return link;
}
// 无参构造器为属性赋初始值
public DuiZhanQueue() {
link = new LinkedList();
}
// 添加元素的方法
public void add(Object obj) {
// 在集合的最前面添加元素
link.addFirst(obj);
}
// 获取元素的方法
public Object get() {
// 将集合中最前面的元素从集合中删除,并将删除的元素返回
// 堆栈排列,先进后出
return link.removeFirst();
}
//判断队列中元素是否为空
public boolean isEmpty(){
return link.isEmpty();
}
}
②队列排列 先进先出
//队列排列,先进先出
public class DuiLieQueue {
// 将LinkedList封装进对象里
private LinkedList link;
// 公共的get/set方法
public void setLink(LinkedList link) {
this.link = link;
}
public LinkedList getLink() {
return link;
}
// 无参的构造器为实行初始化
public DuiLieQueue() {
link = new LinkedList();
}
// 添加元素的方法
public void add(Object obj) {
//在集合的最前面加入元素
link.addFirst(obj);
}
// 获取元素
public Object get() {
//将集合中最后面的元素从集合中删除,并将删除的元素返回
//队列排列,先进先出
return link.removeLast();
}
//判断队列是否为空
public boolean isEmpty(){
return link.isEmpty();
}
}
四、HashTable(Properties)的用法
public static void main(String[] args) throws IOException, IOException {
//创建一个新的属性集(Properties是Map集合的一种)
Properties p = new Properties();
//以流的形式加载一个属性文件
p.load(new FileInputStream("hello.properties"));
String username = p.getProperty("username");
String password = p.getProperty("password");
System .out.println(username);
System .out.println(password);
}
集合遍历的两种方法
List list = new ArrayList();
// 1.增强for循环
for (Object object : list) {
System.out.println(object);
}
// 2.1迭代器
Iterator iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
//2.2 此方法for循环结束以后,it就会在内存中消失,节省内存
for (Iterator iterator = list.iterator();iterator.hasNext();) {
Object obj = iterator.next();
System.out.println(obj);
}
//2.3用次迭代器不会出现并发修改的异常 (List特有的迭代器)
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
Object obj = listIterator.next();
if(obj.equals("aa")){
listIterator.add("bb"); //List特有的迭代器 此处不会出现并发修改的异常
}
}
Map遍历的三种方式
public static void main(String[] args) {
// 创建一个TreeMap实例
Map<String, Integer> map = new TreeMap<>();
// 在TreeMap实例中添加元素
map.put("AA", 12);
map.put("CC", 15);
map.put("EE", 16);
map.put("BB", 19);
map.put("DD", 18);
map.put("FF", 17);
System.out.println(map);
System.out.println("------------方法①---------------");
// 取出Map集合中元素的第一种方法:获取Map中key值放在Set集合中,然后遍历再通过key valued 的值
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
int value = map.get(key);
System.out.println(key + "=" + value);
}
System.out.println("------------方法②---------------");
// 取出Map集合中元素的第二种方法:取出Map中的value的值
Collection<Integer> coll = map.values();
Iterator<Integer> it1 = coll.iterator();
while (it1.hasNext()) {
System.out.println(it1.next());
}
System.out.println("------------方法③---------------");
// 取出Map集合中的entry,然后取出对应的key和value
Set<Entry<String, Integer>> set1 = map.entrySet();
Iterator<Entry<String, Integer>> it2 = set1.iterator();
while (it2.hasNext()) {
Entry<String, Integer> entry = it2.next();
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key + "=" + value);
}
}
集合和数组之间的转换
List asList = Arrays.asList(1,2,3,4,5);
Object[] array = collection.toArray();
Collection collection = new ArrayList();
collection.add(new Student("张三",28));
collection.addAll(c);
boolean contains = collection.contains(new Student("张三",28));
//判断是否包含是根据比较equals()方法比较的 所以对象根据情况复写equals方法
在高并发的情况下 HashMap、ArrayList等是不安全的如何处理
1.用 HashTable
2.Collections工具类
Map map = new HashMap(); Collections.synchronizedMap(map);
List list=new ArrayList(); Collections.synchronizedList(list);
3.HashMap的孪生兄弟类ConcurrentHashMap
ConcurrentHashMap<String, String> hashMap = new ConcurrentHashMap<String, String>();