java容器的深入浅出上
从数组到容器
数组:相同类型的线性存储,重点在于数组是对相同类型数据的有序存储便于查找
但由于其单调性不能满足业务需求,即引入容器
下面将从几个关键点对java容器做一个全面的了解
Collection
继承了Iterable超级接口(此接口中只有一个方法Iteratoriterator就是返回一个迭代器Iterator)Interator的功能就是遍历并选择序列中的对象
1、迭代器的使用
hasNext(); 检查序列中是否还有元素
Next();获得序列中的下一个元素
Collection col = new ArrayList();
col.add(123);
col.add(456);
col.add(789);
Iterator it = col.iterator;
while(it.hasNext()){
System.out.println(it.next());
}
Collection是Collection层级结构中的根接口,JDK不提供此接口的任何直接实现但提供更加具体的子接口(Set,List)实现。一些Collection允许有重复的元素比如List,而另一些则不允许比如Set。
List接口
List是有序的Collection,可以根据索引访问元素,也可以插入重复的值
另:List提供了一种特殊的迭代器,即为ListIterator,即可以在遍历的同时进行插入和替换的功能,
ListIterator it2 = list.listIterator();
while(it2.hasNext()){
if("灭霸".equals(it2.next())){
it2.add("惊奇队长");
}
}
System.out.println(list);
List 接口提供了两种在列表的任意位置高效插入addAll和移除多个元素removeAll的方法
List的子类
1、ArrayList(类)
ArrayLis是基于数组实现的List类,它封装了一个动态的、增长的、允许再分配的Object[ ]数组.它允许对元素进行快速随机访问
当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
List list = new ArrayList();
2、Vector(类)
Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。所以现在已经不太常用了
3、LinkList(类)
LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。
/
* 手写简单容器
* 容器类只能存储字符串,底层由数组实现
* 容器的大小可以根据数据做改变
*/
public class App02 {
public static void main(String[] args) {
MyContainer my = new MyContainer();
my.add("zhangsan");
System.out.println(my.size());
System.out.println(my);
my.add("lisi");
System.out.println(my.size());
System.out.println(my);
my.add("wangwu");
System.out.println(my.size());
System.out.println(my);
//获取
System.out.println(my.get(0));
System.out.println(my.get(1));
System.out.println(my.get(2));
//修改
System.out.println(my.replace(0,"zhaoliu"));
//删除
my.remove(1);
System.out.println(my.size());
System.out.println(my);
}
}
//自定义容器类
class MyContainer{
//存储容器中数据的数组
private String[] arr;
//容器中数据的个数
private int size;
public MyContainer() {
}
//被替换的值
public String replace(int i, String value) {
String v = arr[i];
arr[i] = value;
return v;
}
//删除
public void remove(int index) {
if(index<0 || index>=size) {
throw new ArrayIndexOutOfBoundsException("索引越界啦,敢接改一改!!!");
}
//备份原数组
String[] temp = arr;
//创建新数组
arr = new String[size-1];
//遍历原数组拷贝
//i是原数组的索引 index是要删除的索引
for(int i = 0;i<size;i++) {
if(i>=index) {
if(i==index) {
continue;
}
arr[i-1] = temp[i];
}else {
arr[i] = temp[i];
}
}
//size--
size--;
}
//获取
public String get(int index) {
if(index<0 || index>=size) {
throw new ArrayIndexOutOfBoundsException("索引越界啦,敢接改一改!!!");
}
return arr[index];
}
/*
* 添加方法
* 如果长度不够需要扩容,实现数组的拷贝,数据的存储
*/
public void add(String value) {
/*
* arr = new String[1]; arr[0] = value; size++;
*/
//存储原数组地址,方便一会拷贝使用
String[] temp = arr; //temp指向原数组
//创建新数组,arr永远指向最新的数组
arr = new String[size+1];
//原数组的内容拷贝到新数组
//i为原数组索引,可以作为新数组索引使用
for(int i = 0;i<size;i++) {
arr[i] = temp[i];
}
//新数据添加到最后
arr[size] = value;
//size改变
size++;
}
public int size() {
return this.size;
}
@Override
public String toString() {
return Arrays.toString(arr);
}
}
下一篇继续分享Set接口以及Map接口