java初级-集合

image.png

List 有序的 可重复
Set 无序 不可重复的
Map 映射关系的集合

一. List

1.1ArrayList

<u>List</u> list= new ArrayList<>();//形成多态

底层: 数组

特点:定长 线程不安全

扩容:每次扩容到原来的1.5倍

位于 java.util 包中

如果 List list = new ArrayList();

则默认创建了一个长度为0 的数组。

重点: 如何遍历ArrayList ?

1) 普通的for循环:

for(<u>int</u> i = 0;i<list.size();i++) {

//从集合中将数据取出

String message = list.get(i);

System.out.println(message);

}

2) 增强的for循环:

for (String value : list) {

System.out.println(value);

}

3) 通过集合对象获得迭代器对象

Iterator<String> iterator= list.iterator();

**while**(iterator.hasNext()) {

//取出元素

System.out.println(iterator.next());

}

注意****:

  1. ArrayList list = new ArrauyList(); 在****java 1.6 初始化为长度为****10****的数组****,****在****1.8****之后长度为****0;

  2. 如何需要将****ArrayList 转换成线程安全的集合****:

** 1.Collections**

List<String> list = new ArrayList<>();

list = Collections.synchronizedList(list);

** 2.juc**

并发容器**** CopyOnWriteArrayList

1.2vector

底层:数组

特点:定长 线程安全 比较老旧 不建议使用

扩容:每次扩大两倍

Api与ArrayList相同

遍历:与ArrayList相同

如果我们创建一个vector 集合如下

Vector vector = new Vector();

则默认创建了一个长度为10的数组。

如果指定了参数,则创建(原来长度+参数)长度的数组。

1.3Linkedlist

底层:链表 是一个双向链表

特点:线程不安全 不定长

Api与ArrayList相同

遍历:与ArrayList相同

Add(e) 指的是往链表的尾部添加节点。

链表:

[图片上传失败...(image-92c29a-1585982687109)]

LinkedList get方法的原理 *******

类似于折半查找。先找到中间值

如果查找元素比中间值大,则从右边从后往前遍历

如果查找元素比中间值小,则从左边从头往后遍历

if (index < (size >> 1)) {

            Node<E> x = first;

            for (int i = 0; i < index; i++)

                x = x.next;

            return x;

        } else {

            Node<E> x = last;

            for (int i = size - 1; i > index; i--)

                x = x.prev;

            return x;

        }

1.4 List总结

1)使用的时候api相同

ArrayList  数组

LinkedList  链表

Vector 数组

2)数组:ArrayList Vector

数组定长的

数组的、存放数据 单一类型的

查找 修改 比较快

添加 删除 慢的

链表:LinkedList

查找 修改 慢

添加 删除 快

  1. 集合可以储存多种类型 但是不建议 容易出现类型转换出错

集合不需要关心扩容问题。

4) 不同点

  1. ArrayList 底层数组 线程不安全 查找、修改快

  2. Vector 底层数组 线程安全 查找、修改快 过时

  3. LinkedList 底层链表 线程不安全 增加、删除比较快

二. Set

特点:无序 不可重复

2.1 HashSet

底层:HashMap HashMap 底层 用的 哈希表

Set集合如何进行迭代?

Set<> set = new HashSet<>();

  1. foreach

for(String value : set){

system.out.println(value);

}

  1. 获得迭代器

Iterator<String> iterator = set.iterator();

while(iterator.hasNext()){

System.out.println(iterator.next());

}

注意:

1.在Set中存放字符串 根据字符串的内容判重

2.在Set中存放对象(Student) 根据什么判重?

如何指定判重条件?

Name相同 认为是一个学生

Name id相同

Id 相同

重写 Student类中的 HashCode 和 equals 方法

使用eclipes 快捷方法 重写HashCode 和 equals 方法

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Person other = (Person) obj;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

  1. HashSet 判重使用的HashCode 和 equals方法*******

哈希表: 又称 散列表 -> 数组+链表

根据HashCode计算方法:计算数组下标

Equals 方法 判断是否具有重复元素

HashCode 的作用是快速定位数据

equals方法****的作用是比较链表上的元素是否相同

4.哈希表:又称散列表 -> 数组加链表

[图片上传失败...(image-c604ba-1585982687108)]

2.2 TreeSet

底层:TreeMap TreeMap底层用的红黑树。

使用

  1. 对于简单类型 默认使用字典排序 或者 自然排序

  2. 对于复杂类型 不能直接进行迭代 需要有一下两种方法中的一种:

1) 实体类 实现 接口Comparable

  1. public class Student implement Comparable<Student>{}

  2. 在Student 类 里面 重写compareTo方法

升序

@Override

public int compareTo(Student o){

if(this.id > o.getId){

return 1;

}

If(this,id < o.getId ){

Return -1;

}

Return 0;

降序

@Override

public int compareTo(Student o){

if(this.id > o.getId){

return -1;

}

If(this,id < o.getId ){

Return 1;

}

Return 0;

2) 自定义比较器

Set<E> set = new TreeSet(comparator); //把比较器对象传进来

Comparator<E> comparator = new Comparator<E>(){ //匿名内部类

降序

@Override

If(o1.getId > o2.getId){

Return -1;

}else if(o1.getId < o2.getId){

Return 1

}

Return 0;

}

三. Map

Map 具有映射关系的集合 key-value 语文-99

3.1 HashMap

底层:哈希表

注意:

  1. Key-value 允许使用null值。

  2. Map只能根据Key获得Value,不能根据Value获得Key。

  3. Map中 Key不可重复 而 Value 可重复。

HashMap的迭代:

  1. 把key放入set集合里

Set<E> keySet = map.keySet(); //E 存放Key值 对应的类型。

for(String key : keyset){

sysout.out.println(key + “ :” +map.get(key));

}

  1. 把 Key 和 Value组成一个对象 放到Entry 对象里。

Set<Entry<K,V>> set = map.entrySet();

for(Entry<String, Double> entry: set) {

System.out.println(entry.getKey() +" :"+ entry.getValue());

}

3.2 TreeMap

底层:红黑树

特点:可排序(Key值 可排序)

  1. 如果Key值 是 简单类型 基于字典排序

  2. 如果Key值 是 复杂类型 基于自定义的排序规则

排序规则同TreeSet。另外可用三目运算符。

1>实体类 实现 接口Comparable

1.public class Student implement Comparable<Student>{}

2.在Student 类 里面 重写compareTo方法

@Override 升序 (如果1 在前面 就是升序)

Public int compareTo(Student o){

return this.getAge > o.getAge ? 1 : ( this.getAge < o.getAge)?-1:0;

}

2>创建自定义比较器 Comparator 使用匿名内部类的形式 重写compare方法

TreeMap<Student, Integer> map= new TreeMap<>(new Comparator<Student>() {

@Override

public intcompare(Student o1, Student o2) {

// TODO Auto-generated method stub

return o1.getAge() > o2.getAge() ? 1 : (o1.getAge() < o2.getAge())?-1:0;

}

});

TreeMap的迭代: ****同HashMap

  1. 把key放入set集合里

Set<E> keySet = map.keySet(); //E 存放Key值 对应的类型。

for(String key : keyset){

sysout.out.println(key + “ :” +map.get(key));

}

  1. 把 Key 和 Value组成一个对象 放到Entry 对象里。

Set<Entry<K,V>> set = map.entrySet();

for(Entry<String, Double> entry: set) {

System.out.println(entry.getKey() +" :"+ entry.getValue());

}

3.3Hashtable

A****pi的使用与HashMap相同。

特点:1.是线程安全的类 同步集合

  1. key – value 不允许使用 null值。

3.4Map集合的补充

1.关于Map 集合的扩容问题

HashMap map = new HashMap();

默认创建的数组的长度为16, 加载因子为0.75 。当添加的数据数 到达 16*0.75 = 12时

Map集合将在底层进行扩容 扩容到原来的两倍

  1. 在 JDK8 中 HashMap的底层不再单纯的是哈希表了

底层: 哈希表 + 红黑树

如果哈希表中 链表的长度 >= 7 则转换为红黑树。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容