是一个长度可变且可以存储多个数(对象)据的容器
Collection<E>是集合的顶级接口
<E>是泛型 用于指定集合元素的数据类型,由于我们泛型的指定所以只能是引用类型
int[] arr;arr的数据类型是数组类型,arr的元素是int类型
Collection<String>c; c的数据类型是引用类型,c中的元素是String类型。
集合存储基本类型数据 1 2 4 可以自动封装成包装类 Integer in=1; in可以存储在集合中
1.Collection<E>是集合的顶级接口
//创建集合对象 Collection<String> c=new ArrayList<String>(); //添加元素 c.add("徐"); c.add("love"); c.add("李"); //输出集合 System.out.println(c); //[徐, love, 李] //删除元素 c.remove("李"); //没有要删除的元素就什么都不做 c.remove("火"); System.out.println(c); //[徐, love] //清空集合 //c.clear(); //判断元素是否包含在集合元素中 System.out.println(c.contains("徐")); //true //判断集合中元素是否为空 System.out.println(c.isEmpty()); //集合元素的个数 System.out.println(c.size()); //返回包含此集合中所有元素的数组。返回类型是object、 Object[] os=c.toArray(); //在转换的过程中指明要转换的数组元素的类型 String[] ss=c.toArray(new String[2]);
我们要谈collection下的三个子接口 list set queue
2.List(列表)是一个接口,需要实现类来实现
特征:1.存入数据有序 2.可以根据下标操作添加元素3.可以存储我们重复元素
//创建list集合对象 List<String> l=new ArrayList<String>(); //添加元素 l.add("a"); l.add("a3"); l.add("a2"); l.add("a02"); System.out.println(l);//[a, a3, a2, a02] //根据下标插入元素 l.add(3,"b"); System.out.println(l);//[a, a3, a2, b, a02] //可以根据元素也可以根据下标删除元素 l.remove(0); System.out.println(l);//[a3, a2, b, a02] //根据下标返回元素 System.out.println(l.get(1)); //a2 //返回指定元素第一次出现的下标值,如果没找到就返回-1 System.out.println(l.indexOf("a2")); //1 l.set(0,"123");//用指定元素替换此列表中指定位置的元素 System.out.println(l);//[123, a2, b, a02] List<String> l2=l.subList(1, 3); System.out.println(l2);
实现类:ArrayList,LinkedList,Vector,Stack
(1)ArrayList():有序表底层由数组来实现的,默认数组的初始长度是10,根据底层右移运算进行扩容,每次在原来的基础上扩容一半,可以指定容量
特点:查询速度较高,增删元素效率较低线程不安全集合
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //elementData是底层创建的数组 int newCapacity = oldCapacity + (oldCapacity >> 1); //右移操作是除2 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
//创建list集合对象 List<String> l=new ArrayList<String>(); //添加元素 l.add("a"); l.add("a3"); l.add("a2"); l.add("a02"); System.out.println(l);//[a, a3, a2, a02] //根据下标插入元素 l.add(3,"b"); System.out.println(l);//[a, a3, a2, b, a02] //可以根据元素也可以根据下标删除元素 l.remove(0); System.out.println(l);//[a3, a2, b, a02] //根据下标返回元素 System.out.println(l.get(1)); //a2 //返回指定元素第一次出现的下标值,如果没找到就返回-1 System.out.println(l.indexOf("a2")); //1 l.set(0,"123");//用指定元素替换此列表中指定位置的元素 System.out.println(l);//[123, a2, b, a02] System.out.println(l.subList(1, 3)); System.out.println(l);
用数组重写ArrayList<String>的方法
1 public class ListArrays { 2 3 public static void main(String[] args) { 4 ListA a=new ListA(); 5 a.add("adg"); 6 a.add("g"); 7 a.add("adu"); 8 System.out.println(a); 9 } 10 11 } 12 class ListA 13 { 14 //存储数据的数组 15 String[] data; 16 //元素个数以及数组下标 17 int size=0; 18 //无参构造--默认初始容量为10 19 public ListA() { 20 data=new String[10]; 21 } 22 //有参构造---指定初始容量 23 public ListA(int initCaptity) { 24 data=new String[initCaptity]; 25 } 26 //数组扩容 27 public void grow() { 28 //判断数组原长度是否为1 29 if(data.length<=1) //为什么要是1 因为下面1/2还是0等于没扩容 30 { 31 data=Arrays.copyOf(data, 1); 32 } 33 //在原来的基础上加上一半 34 data=Arrays.copyOf(data, data.length+(data.length>>1)); 35 } 36 37 //判断下标是否越界 38 public void out(int index) { 39 40 if(index<0||index>=size) //下标与元素个数比较 41 { 42 throw new IllegalArgumentException("index+"+index); 43 } 44 } 45 46 //添加元素 47 public void add(String str) 48 { 49 if(size>=data.length) 50 { 51 grow(); 52 } 53 //往数组里添加元素 54 data[size++]=str; 55 56 } 57 58 //插入元素 59 public void add(int index,String str) 60 { 61 //是否需要扩容,保证有足够的空间插入 62 if(size>=data.length) 63 { 64 grow(); 65 } 66 //判断下标是否越界 67 if(index<0||index>size) //下标与元素个数比较 68 { 69 throw new IllegalArgumentException("index+"+index); 70 } 71 //一次把index后面的数组元素往后赋值 72 for(int i=size-1;i>=index;i--) 73 { 74 data[i+1]=data[i]; 75 } 76 //插入这个元素 77 data[index]=str; 78 //元素个数增加 79 size++; 80 //也可以直接将要移动的数组部分往后复制一位。 81 //System.arraycopy(data,index,data,index+1,size-index); 82 } 83 //根据下标删除 84 public void remove(int index) 85 { 86 //判断下标值是否越界 87 out(index); 88 //依次把index的后面的元素往前移动 89 for(int i=index;i<size-1;i++) 90 { 91 data[i]=data[i+1]; 92 } 93 size--; 94 //System.arraycopy(data,index+1,data,index,size-(index+1)); 95 96 } 97 //根据元素删除 98 public void remove(String str) { 99 //是否能找到; 100 int i=indexOf(str); 101 if(i!=-1) 102 { 103 remove(i); 104 } 105 } 106 //返回元素第一次出现的下标值 107 public int indexOf(String str) 108 { 109 //遍历数组依次比较 110 for(int i=0;i<size;i++)//只比元素 111 { 112 //判断是否相等 113 if(data[i]==str||data[i]!=null&&data[i].equals(str)) 114 { 115 //返回找的到的元素下标 116 return i; 117 } 118 119 } 120 //数组中没有出现 121 return -1; 122 } 123 //清空集合 124 public void clear() { 125 size=0; 126 } 127 //判断是否包含元素 128 public boolean contains(String str) 129 { 130 return(indexOf(str)!=-1); 131 } 132 //判断集合是否为空 133 public boolean isEmpty() { 134 return size==0; 135 } 136 //替换元素 137 public void set(int index,String str) 138 {//判断是否越界 139 out(index); 140 //替换 141 data[index]=str; 142 } 143 //返回元素个数 144 public int size() { 145 return size; 146 } 147 //截取子列表 148 public ListA subList(int fromIndex,int toIndex) { 149 //是否越界 150 out(fromIndex); 151 out(toIndex); 152 //判断下标大小是否正确 153 if(toIndex<fromIndex) { 154 throw new IllegalArgumentException("FromIndex"+fromIndex+"ToIndex"+toIndex); 155 156 } 157 //新建列表 158 //指定新列表长度 159 int count=toIndex-fromIndex; 160 ListA list=new ListA(count); 161 //拷贝元素 162 System.arraycopy(data, fromIndex, list.data, 0, count); 163 //赋值size -----把复制的元素个数赋值给新列表的size 164 list.size=count; 165 //返回新列表 166 return list; 167 168 } 169 //重写ToString() 170 @Override 171 public String toString() { 172 //创建StringBuilder的对象 173 StringBuilder sb=new StringBuilder("["); 174 //拼接字符串数组中的元素 175 for(int i=0;i<size;i++) 176 { 177 sb.append(data[i]).append(", "); 178 } 179 //转成字符串 180 String s=sb.toString(); 181 //截取字串 ---后面的, 不要了 182 if(size>0) //只有在字符串中有元素 183 s=s.substring(0,s.length()-2); 184 return s+="]"; 185 } 186 187 }