集合
什么是集合?
集合也是一种容器,也可以存放数据。随着我们学习技术的深入,那么我们在程序中创建的对象也会越来越多。这时在程序中就要想办法先把这些对象给存储起来,然后在需要使用这些对象的时候从容器中把对象取出,再去使用这些对象。
集合与数组的区别:
1)从长度来讲:
数组:需要固定长度。
集合:长度可以改变,可以根据保存的数据进行扩容。
2)从存储内容上:
数组:可以存储基本类型数据,还可以存储引用类型的数据(比如:String和上述演示的Student类)。
集合:只能存储引用类型的数据,也就是说集合只能存储类的对象。
3)从存储类型上:
数组:只能存储相同类型的数据。
集合:可以存储不同类型的数据,集合中可以存储任意类型的引用数据类型。
集合
迭代器
增强for
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器。
foreach循环,也称为高级for循环或者叫做增强for循环。它可以简化普通的for循环。foreach 不能完全代替普通的for循环。
普通for循环的格式:
for( 循环初始化; 循环条件 ; 修改循环条件 ){
循环体
}
foreach循环:
for( 数组或集合中元素的类型 变量名 : 数组名或集合名 ){
//变量名所指的空间中,保存的是从数组或者集合中取出的数据
}
注意:它只能用来遍历数组或是集合,其实它的底层是一个迭代器。
例子:
public class NBFor {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<String>();
coll.add("小河神");
coll.add("老河神");
coll.add("神婆");
//使用增强for遍历
for(String s :coll){ //接收变量s代表 代表被遍历到的集合元素
System.out.println(s);
}
}
}
ArratList
ArrayList的使用
查看类
ava.util.ArrayList <E>
:该类需要 import导入使后使用。
<E>
,表示一种指定的数据类型,叫做泛型。E
,取自Element(元素)的首字母。在出现E
的地方,我们使用一种引用数据类型将其替换即可,表示我们将存储哪种引用类型的元素。代码如下:
ArrayList<String>,ArrayList<Student>
查看构造方法
public ArrayList()
:构造一个内容为空的集合。
基本格式:
ArrayList<String> list = new ArrayList<String>();
在JDK 7后,右侧泛型的尖括号之内可以留空,但是<>仍然要写。简化格式:
ArrayList<String> list = new ArrayList<>();
查看成员方法
-
public boolean add(E e)
: 将指定的元素添加到此集合的尾部。参数
E e
,在构造ArrayList对象时,<E>
指定了什么数据类型,那么add(E e)
方法中,只能添加什么数据类型的对象。
需求:使用ArrayList类,存储三个字符串元素
public class Test02StudentArrayList {
public static void main(String[] args) {
//创建集合对象
ArrayList<String> list = new ArrayList<>();
//定义字符串对象
String s1 = "曹操";
String s2 = "刘备";
String s3 = "孙权";
//打印ArrayList集合
System.out.println(list);
//把字符串作为元素添加到集合
list.add(s1);
list.add(s2);
list.add(s3);
//打印ArrayList集合
System.out.println(list);
}
}
常用方法和遍历
对于元素的操作,基本体现在——增、删、查。常用的方法有:
-
public boolean add(E e)
:将指定的元素添加到此集合的尾部。
-
public E remove(int index)
:移除此集合中指定位置上的元素。返回被删除的元素。
-
public E get(int index)
:返回此集合中指定位置上的元素。返回获取的元素。
-
public int size()
:返回此集合中的元素数。遍历集合时,可以控制索引范围,防止越界。
这些都是最基本的方法,操作非常简单,代码如下:
public class ArrayListMethod {
public static void main(String[] args) {
//创建集合对象
ArrayList<String> list = new ArrayList<String>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//public E get(int index):返回指定索引处的元素
System.out.println("get:"+list.get(0));
System.out.println("get:"+list.get(1));
System.out.println("get:"+list.get(2));
//public int size():返回集合中的元素的个数
System.out.println("size:"+list.size());
//public E remove(int index):删除指定索引处的元素,返回被删除的元素
System.out.println("remove:"+list.remove(0));
//遍历输出
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
}
迭代器遍历List集合
for循环
//循环3要素 //1.循环初始化值 Iterator<Integer> i = list.iterator(); //2.布尔表达式 list.iterator(); //3.修改布尔表达式 i.next(); List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); // i.hasNext() 判断是否有下一个元素 for (Iterator<Integer> i = list.iterator(); i.hasNext();) { //next() 取出下一个元素 int x=i.next(); System.out.println(x); }
While循环
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
Iterator<Integer> i = list.iterator();
// i.hasNext() 判断是否有下一个元素
while (i.hasNext())
{
//next() 取出下一个元素
System.out.println(i.next());
}
while循环的迭代和for循环的迭代有什么不同?
while循环的迭代,由于初始化迭代器对象在while循环上面,在整个while循环结束后,迭代器对象还可以继续使用,但是集合中已经没有数据了,如果还仍然使用迭代器对象继续获取数据,会报异常,如果还要获取,需要重新在获取一个迭代器对象。所以对于while循环当迭代器对象使用完之后,迭代器就会变成一个没有用的垃圾,占内存。
对于for循环的迭代,由于初始化迭代器对象在for循环小括号中,在整个for循环结束后,迭代器对象就不能继续使用,也不会占内存,所以建议大家以后在开发中使用迭代器遍历集合最好使用for循环。
ArrayList的底层是数组数据结构
ArrayList的存:
1.默认情况下,ArrayList会生成一个大小是10的object类型数组
2.在ArrayList中size指的是数组中存放元素的个数,elementData.length表示数组的长度,但是由于刚创建的集合中没有放任何的元素,所以size=0.
ArrayList的扩容:
如果加入元素后数组大小不够会先进行扩容,每次扩容都将数组的大小增大原先的一半。比如:为扩容前的数组大小是10,那么扩容后的大小就是10+10*1/2=15。ArrayList的最大长度是2的32次方
ArrayList删除指定元素:
删除指定元素后,ArrayList会将后面部分的元素依次往上挪一个位置。所以,下一个需要访问的下标还是当前下标。所以必须得减一才能把所有元素都遍历完。
size和modCount有什么区别:
size是ArrayList中元素的个数,modCount记录的是关于元素的数目被修改的次数。在fail-fast中有明显的用处。