Java基础之集合
Posted Ocean:)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础之集合相关的知识,希望对你有一定的参考价值。
集合
开发中使用数组的弊端
- 数组中能够使用的方法非常少,功能方法需要程序员自己完成
- 数据类型单一化,不支持多种情况
- 数组容量定义之后不能改
集合的优势
- 方法多样,功能完善
- 数据类型多样化
- 容量可变
集合架构
Java中集合的 总接口 Collection
Java中所有和集合有关的内容,都是Collection接口的子接口或者实现类
interface Collection<E>
interface List<E> List接口,有序可重复
class ArrayList<E> 可变长度数组结构
class LinkedList<E> 双向链表结构
class Vector<E> jdk1.0 线程安全的ArrayList,如果不考虑线程安全问题,推荐使用ArrayList
interface Set<E> Set接口,无序不可重复
HashSet<E> 底层存储数据方式采用哈希表
TreeSet<E> 底层存储数据方式采用平衡二叉树
Collection接口下的常用方法
增:
boolean add(E e);
存入元素当前集合对象中,要求的数据类型是E类型,也就是泛型对应的具体数据类型
boolean addAll(Collection<? extends E> c);
括号中的内容就相当于 class Dog extends Animal中Dog被替换为?,? extends E泛型的上限
要求存入的集合c中,存储的元素要么是E类型,要么是E类的子类
删:
void clear();
清空整个集合
boolean remove(Object obj);
删除集合中的指定元素
boolean removeAll(Collection<?> c);
删除两个集合的交集
boolean retainAll(Collection<?> c);
保留两个集合的交集
改
查:
int size();
返回集合中有效元素个数
boolean isEmpty();
判断当前集合是否为空
boolean contains(Object obj);
判断指定元素在当前集合中是否存在
boolean containsAll(Collection<?> c);
判断集合c是不是当前集合的子集合
实例
package cn.ocean888_b;
import java.util.ArrayList;
import java.util.Collection;
import javax.sound.midi.Soundbank;
public class Demo2 {
public static void main(String[] args) {
/*
* 因为Collection<E>使用一个接口,接口没有自己的类对象
* 需要使用Collection接口的实现类来完成演示过程ArrayList<E>
* 这里就用到了泛型
*/
Collection<String> c = new ArrayList<String>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
System.out.println(c);
Collection<String> c1 = new ArrayList<String>();
c1.add("first");
c1.add("second");
c1.add("thrid");
c1.add("forth");
System.out.println(c1);
c.addAll(c1);
System.out.println(c);
System.out.println("size:" + c.size());
System.out.println(c.isEmpty());
System.out.println(c.containsAll(c1));
System.out.println(c.contains("forth"));
}
}
迭代器
通过集合对象获取对应的Iterator迭代器
Iterator iterator
-
常用方法:
boolean hasNext();
判断当前Iterator是否可以继续运行
E next()
获取Iterator当前指向元素,并且指向下一个元素
void remove();
删除next获取的元素
注意:remove方法仅能删除next获取的元素,并且时紧挨着使用
List集合接口特征和方法
特征:
有序,可重复
有序:添加顺序和存储顺序一致
可重复:相同元素可以同时添加
List接口下的实现类,存在一定的下标操作机制
ArrayList底层数组形式操作,可以通过下标直接访问
LinkedList底层是一个双向链表结构
增:
-
add(E e);
List接口下,当前方法是添加元素到集合的末尾,尾插法
-
addAll(Collection<?extends E?> c);
List接口下,当前方法是添加另一个集合到当前集合末尾,要求添加的集合中保存的元素和当前集合保存元素一致,或者是当前集合保存元素的子类
-
add(int index, E e);
在指定的下标位置,添加指定元素
-
addAll(int index, Collection<?extends E?> c);
在指定的下标位置,添加指定的集合,集合要求同addAll方法
删:
-
void clear();
清空整个集合
-
remove(Object obj);
删除集合中的指定元素
-
removeAll(Collection<?> c);
删除集合中两个集合的交集
-
retainAll(Collection<?> c);
保留两个集合的交集
-
remove(int index);
删除集合中的指定下标的元素
改:
-
E set(int index,E e);
使用指定元素替换指定下标index的元素,返回值是被替换掉的元素
查:
-
int size();
有效元素个数
-
boolean isEmpty();
判断当前集合是否为空
-
boolean contains(Object obj);
判断集合中是否包含某个元素
-
boolean containsAll(Collection<?> c);
判断集合中是否包含某个子集
-
int indexOf(Object obj);
找出指定元素在集合中的第一次出现的位置
-
int lastIndexOf(Object obj);
找出指定元素在集合中最后一次出现的位置
-
E get(int index);
获取指定下标的元素
-
List subList(int fromIndex, int endIndex);
获取当前集合的子集合
实例:
package cn.ocean888;
import java.util.ArrayList;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
// 注意导包导入util的包
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
List<String> list2 = new ArrayList<String>();
list2.add("1");
list2.add("2");
list2.add("3");
list2.add("4");
System.out.println(list);
list.addAll(2, list2);
System.out.println(list.remove(3));
System.out.println(list);
String str = list.set(2, "2");
System.out.println(str);
System.out.println(list);
list.add(3, "1");
list.add(4, "2");
System.out.println(list);
int index = list.indexOf("2");
System.out.println(index);
int lastIndex = list.lastIndexOf("2");
System.out.println(lastIndex);
// lastList
// java中所有的范围约束都是左闭右开,要头不要尾
List<String> subList = list.subList(0, 5);
System.out.println(subList);
}
}
ArrayList可变长度数组
特征:
数组形式的操作方式,查询效率高,但是删除,增加效率低
数组:
Object类型数组
方法:
ArrayList使用的方法基本上都是从List接口中遵从实现的方法
-
特征:
ensureCapacity(int minCapacity);
判断当前容量是否足够
trimTosize();
截断整个数组容量 => size有效元素个数
性能问题
线性表
- 增删慢
- 增加元素有可能需要调用grow方法,对数组进行扩容,操作工程中需要大量的移动和拷贝过程,浪费时间
- 在某一个位置添加删除元素,后边的元素位置都需要移动
- 查询快
计算机内地址查询采用基地址加偏移量的方式
null:
null ==> 0x内存中编号为0的地址
该地址收到系统保护,任何程序读取,写入0x0地址,系统将直接杀死程序
一般用于开发中初始化引用数据类型的变量,利用null报错,NullPointerException
debug
先下断点
f5,进入函数,单步调试
f6,不进入函数,跳步
LinkedList链表
底层是一个双向链表
特征:
- 增删快
- 不涉及数据的移动,仅更改指针,速度快
- 查找慢
- 需要从链表的开始位置一个一个节点跳转查询,速度慢
LinkedList使用的方法,大部分都是从List接口中遵从实现的方法
节点
- 向前的引用prev
- 存储元素的引用data
- 向后的引用next
class Node { private Node prev;
private Node next;
private E value;
}
特征
以上是关于Java基础之集合的主要内容,如果未能解决你的问题,请参考以下文章