java基础8——几个重要的API之集合类

1. 集合框架体系

---|Collection: 单列集合

           ---|List: 有存储顺序, 可重复

              ---|ArrayList:    数组实现, 查找快, 增删慢

                                       由于是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快

              ---|LinkedList:   链表实现, 增删快, 查找慢

                                  由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素. 这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低

              ---|Vector:   和ArrayList原理相同, 但线程安全, 效率略低

                              和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低

           ---|Set: 无存储顺序, 不可重复

              ---|HashSet

              ---|TreeSet

              ---|LinkedHashSet

---| Map: 键值对

       ---|HashMap

       ---|TreeMap

       ---|HashTable

       ---|LinkedHashMap

2. 集合的使用场景

2.1 connection

我们需要保存若干个对象的时候使用集合

2.2 list

如果我们需要保留存储顺序, 并且保留重复元素, 使用List.

如果查询较多, 那么使用ArrayList

如果存取较多, 那么使用LinkedList

如果需要线程安全, 那么使用Vector

2.3 set

如果我们不需要保留存储顺序, 并且需要去掉重复元素, 使用Set.

如果我们需要将元素排序, 那么使用TreeSet

如果我们不需要排序, 使用HashSet, HashSet比TreeSet效率高.

如果我们需要保留存储顺序, 又要过滤重复元素, 那么使用LinkedHashSet

3. 集合类

3.1 概述

Collection接口有两个子接口:List(链表|线性表)、Set(集)

特点:

Collection中描述的是集合共有的功能(CRUD)

List可存放重复元素,元素存取是有序的

Set不可以存放重复元素,元素存取是无序的

java.util.Collection

       ---| Collection      描述所有接口的共性

           ----| List接口 可以有重复元素的集合

           ----| Set  接口 不可以有重复元素的集合

 

3.2 Collection接口的共性方法

增加:

       1:add()   将指定对象存储到容器中

                      add 方法的参数类型是Object 便于接收任意对象

       2:addAll() 将指定集合中的元素添加到调用该方法和集合中

删除:

       3:remove() 将指定的对象从集合中删除

       4:removeAll() 将指定集合中的元素删除

修改

       5:clear() 清空集合中的所有元素

判断

       6:isEmpty() 判断集合是否为空

       7:contains() 判断集合何中是否包含指定对象

           

       8:containsAll() 判断集合中是否包含指定集合

                            使用equals()判断两个对象是否相等 

获取:   9:int size()    返回集合容器的大小

 

转成数组10: toArray()   集合转换数组

3.3 List集合

---| Iterable     接口

          Iterator iterator()

    ----| Collection     接口

       ------| List      接口 元素可以重复,允许在指定位置插入元素,并通过索引来访问元素

1. list集合特有的方法

1:增加
        void add(int index, E element) 指定位置添加元素            
        boolean addAll(int index, Collection c) 指定位置添加集合  
2:删除
E remove(int index) 删除指定位置元素

3:修改
		E set(int index, E element)    返回的是需要替换的集合中的元素
4:查找:
        E get(int index)             注意: IndexOutOfBoundsException
		int indexOf(Object o)         // 找不到返回-1
		lastIndexOf(Object o) 
5:求子集合
		 List<E> subList(int fromIndex, int toIndex) // 不包含toIndex

2. ArrayList

体系:

--| Iterable

             ----| Collection

               ------| List

                 ---------| ArrayList  底层采用数组实现,默认10。每次增长60%,((oldCapacity * 3)/2 + 1) 查询快,增删慢。

               ---------| LinkedList

实现原理:数组实现, 查找快, 增删慢

数组为什么是查询快?因为数组的内存空间地址是连续的.

    ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。

    当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。

由于ArrayList是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快

可以考虑,假设向数组的0角标未知添加元素,那么原来的角标位置的元素需要整体往后移,并且数组可能还要增容,一旦增容,就需要要将老数组的内容拷贝到新数组中.所以数组的增删的效率是很低的

3. LinkedList

体系:

--| Iterable

             ----| Collection

               ------| List

                 ---------| ArrayList  底层采用数组实现,默认10。每次增长60%,((oldCapacity * 3)/2 + 1) 查询快,增删慢。

               ---------| LinkedList  底层采用链表实现,增删快,查询慢。

原理:链表实现, 增删快, 查找慢

由于LinkedList:在内存中的地址不连续,需要让上一个元素记住下一个元素.所以每个元素中保存的有下一个元素的位置.虽然也有角标,但是查找的时候,需要从头往下找,显然是没有数组查找快的.但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,让新元素记住下一个元素就可以了.所以插入很快.

由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素. 这样的增删效率较高。

但查询时需要一个一个的遍历, 所以效率较低

特有方法:

1. addFirst(E e)

2. addLast(E e)

3. getFirst()

4. getLast()

5. removeFirst()

6. removeLast()

如果集合中没有元素,获取或者删除元素抛:NoSuchElementException

数据结构:

1. 栈 (1.6),先进后出

push()

pop()

2. 队列(双端队列1.5),先进先出

offer()

poll()

返回逆序的迭代器对象

descendingIterator()   返回逆序的迭代器对象

小例子:

import java.util.Iterator;
import java.util.LinkedList;

public class Demo3 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		list.add("西游记");
		list.add("三国演义");
		list.add("石头记");
		list.add("水浒传");
		list.add("全球通史");
		list.addFirst("史记");
		list.addLast("呐喊");
		// list.addFirst(null);
		// list.addLast(null);
		System.out.println(list);
		// 获取指定位置处的元素。
		String str = (String) list.get(0);
		// 返回此列表的第一个元素。
		String str2 = (String) list.getFirst();
		System.out.println(str.equals(str2));

		// 获取指定位置处的元素。
		String str3 = (String) list.get(list.size() - 1);
		// 返回此列表的最后一个元素。
		String str4 = (String) list.getLast();
		System.out.println(str3.equals(str4));

		// 获取但不移除此列表的头(第一个元素)。
		Object element = list.element();
		System.out.println(element);

		int size = list.size();
		System.out.println(size);
}

迭代

import java.util.Iterator;
import java.util.LinkedList;

public class Demo3 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		list.add("西游记");
		list.add("三国演义");
		list.add("石头记");
		list.add("水浒传");
		list.add("全球通史");
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String next = (String) it.next();
			System.out.println(next);
		}
	}
}

逆序迭代

import java.util.Iterator;
import java.util.LinkedList;

public class Demo6 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		list.add("aa");
		list.add("bb");
		list.add("cc");
		Iterator dit = list.descendingIterator();
		while (dit.hasNext()) {
			System.out.println(dit.next());
		}
	}
}

注意:可以使用该集合去模拟出队列(先进先出) 或者堆栈(后进先出) 数据结构。

堆栈(后进先出)

//堆栈(后进先出) 数据结构
public class Demo3 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		// 压栈,先进后出
		list.push("西游记");
		list.push("三国演义");
		list.push("石头记");
		list.push("水浒传");
		System.out.println(list);
		// 弹栈
		String str1 = (String) list.pop();
		System.out.println(str1);
		String str2 = (String) list.pop();
		System.out.println(str2);
		String str3 = (String) list.pop();
		System.out.println(str3);
		String str4 = (String) list.pop();
		System.out.println(str4);
        System.out.println(list.size());// 0
		System.out.println(list); //[]
	}
}

队列,先进先出

import java.util.LinkedList;

public class Demo3 {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		// 队列,先进先出
		list.offer("西游记");
		list.offer("三国演义");
		list.offer("石头记");
		list.offer("水浒传");
		System.out.println(list);
		// 出队列
		System.out.println(list.poll());
		System.out.println(list.poll());
		System.out.println(list.poll());
		System.out.println(list.poll());

		System.out.println(list.size());

		System.out.println(list.peek()); // 获取队列的头元素,但是不删除
		System.out.println(list.peekFirst()); // 获取队列的头元素,但是不删除
		System.out.println(list.peekLast()); // 获取队列的最后一个元素但是不删除

	}
}

ArrayList 和 LinkedList的存储查找的优缺点

4. ArrayList 和 LinkedList的存储查找的优缺点

1、ArrayList 是采用动态数组来存储元素的,它允许直接用下标号来直接查找对应的元素。但是,但是插入元素要涉及数组元素移动及内存的操作。总结:查找速度快,插入操作慢。

2、LinkedList 是采用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快

问题:有一批数据要存储,要求存储这批数据不能出现重复数据,ArrayList、LinkedList都没法满足需求。解决办法:使用 set集合。

5. Vector

1. Vector: 描述的是一个线程安全的ArrayList

2. ArrayList: 单线程效率高

3. Vector   : 多线程安全的,所以效率低

4. vector特有的方法:

4.1. void addElement(E obj)  在集合末尾添加元素

 4.2 E elementAt( int index) 返回指定角标的元素

 4.3 Enumeration elements()  返回集合中的所有元素,封装到Enumeration对象中

 4.4 Enumeration 接口:

                                        boolean hasMoreElements()  测试此枚举是否包含更多的元素。

                                        E nextElement()   如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值