集合:Collection
- Collection是集合的顶级父类:是一个接口,其下又两个子类:List和Set。
- List:元素可重复,List都是有序的。
- Set:元素不可重复,Set大部分是无序的。
- Collection常用方法
方法 | 说明 |
---|---|
int size(); | 返回包含对象的个数 |
boolean isEmpty(); | 返回是否为空 |
boolean contains(Object o); | 判断是否包含指定对象 |
void clear(); | 清空集合 |
boolean add(E e); | 向集合中添加对象 |
boolean remove(Object o); | 从集合中删除对象 |
boolean addAll(Collection<?extends E> c); | 将另一集合中的所有元素添加到集合中 |
boolean removeAll(Collection<?> c); | 删除集合中与另外一个集合中相同的全部元素 |
Iterator<E> iterator(); | 返回该集合的对应的迭代器 |
List
- List:可重复集的父接口,是Collection的子接口,用于定义线性表数据结构;可以将List理解为存放对象的数组,只不过其元素个数可以动态的增加或减少。
- List接口的两个常用的实现类为ArrayList和LinkedList,分别用动态数组和链表的方式实现了List接口。
-
可以认为ArrayList和LinkedList的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList更适合于随机访问而LinkedList更适合插入和删除;在性能要求不是特别苛刻的情形下可以忽略这个差别。
import java.util.ArrayList;
import java.util.List;
/**
* List(线性表)
* List本身不能实例化!我们可以使用其几个子类实现
*/
public class ListTest {
public static void main(String[] args) {
/**
* 创建一个ArrayList实例
* 使用List我们不需要在创建的时候考虑容量。
* 集合的容量是根据其所保存的元素决定的。
* 换句话说,集合的容量是可以自动扩充的。
*/
List list = new ArrayList();//多态的写法,推荐使用
//ArrayList list = new ArrayList();正常的写法
/**
* add方法,向集合末尾追加一个新元素
* add(Object obj)
* 从改方法的参数定义不难看出,集合可以存放任意类型的元素,
* 但在实际编程中我们发现,几乎不会向集合中存放一种以上不同
* 类型的元素。
*/
list.add("One");//向集合中添加一个字符串。
list.add("Two");
list.add("Three");
//不建议这样操作!尽量不在同一个集合中存放不同类型元素
//list.add(1);
/**
* ArrayList同样重新了toString()方法。
* 返回的是每个元素的toString()返回值的序列
* System.out.println()方法默认会调用对象的toString()方法
*/
System.out.println(list);//[One, Two, Three]
/**
* contains(Object obj)方法检测给定对象是否被包含在集合中
* 检测规则是将obj对象与集合中每个元素进行equals比较
* 若equals返回true,则改方法返回true。
* 若比对了所以元素均没有equals为true的则返回false
* 被存放元素的equals方法在集合中决定的事情还很多!
* 是否重写元素的equals方法对集合的操作结果有很大的效果不同。
*/
System.out.println(list.contains("One"));//true
list.remove("One");
System.out.println(list);//[Two, Three]
list.clear();//清空集合
System.out.println(list);//[]
List list1 = new ArrayList();
List list2 = new ArrayList();
List list3 = new ArrayList();
//为第一个集合添加元素
list1.add("One");
list1.add("Two");
list1.add("Three");
//为第二个集合添加元素
list2.add("Four");
list2.add("Five");
//为第三个集合添加元素
list3.add("One");
/**
* 将集合2的所有元素放到集合1中
* 集合的addAll(Collection c)
* 该方法运行将c对应的集合中的所有元素存入该集合
* 注意,这里的参数为Collection,所有换句话说,任何集合
* 类型都可以将其元素存入其它集合中!
*/
list1.addAll(list2);
list1.addAll(list3);
System.out.println(list1);//[One, Two, Three, Four, Five, One]
//从list1中删除list3中相同(equals为true的)的元素
list1.removeAll(list3);
System.out.println(list1);//[Two, Three, Four, Five]
//保留list1中与list3中相同(equals为true)的元素
list1.retainAll(list2);//list1和list2取交集
System.out.println(list1);//[Four, Five]
/**
* 想获取集合中的元素我们可以使用get()方法
* Object get(int index);
* 根据元素下标获取对应位置的元素并返回
* 这里元素下标和数组相似。
*/
//因为get方法是以Object类型返回的元素,所有需要转型
String element = (String) list1.get(0);//获取第一个元素
System.out.println(element);//Four
//遍历集合
for (int i = 0; i < list1.size(); i++) {
System.out.println(list1.get(i));
}
/*
* set方法,用于修改集合中的元素
* Object set(int index,Object newElement);
* 将index位置的元素修改为newElement,修改后会将被修改的元素返回。
*/
Object old = list1.set(0,"四");
System.out.println("被替换的元素:"+old);//被替换的元素:Four
System.out.println(list1);//[四, Five]
/**
* 向集合中插入一个元素
* add(int index,Object newElement);
* 使用add的重载方法,我们可以向index指定位置插入newElement
* 原位置的元素自动向后移动
* 所谓的“插队”
*/
list1.add(1,"4.5");
System.out.println(list1);//[四, 4.5, Five]
/**
* 根据下标删除元素
* Object remove(int index)
* 将集合中下标为index的元素删除,并将被删除的元素返回
* boolean remove(Object obj)//这个方法删除equals方法返回true的对象后,返回true,否则返回false
*/
Object obj = list1.remove(2);
System.out.println("被删除的元素:"+obj);//被删除的元素:Five
System.out.println(list1);//[四, 4.5]
list1.add("4.5");
list1.add("4.5");
System.out.println(list1);//[四, 4.5, 4.5, 4.5]
System.out.println(list1.indexOf("4.5"));//1
System.out.println(list1.lastIndexOf("4.5"));//3
/**
* 如何将一个集合转换为数组?
* Object[] toArray()
* 该方法会将集合以对象数组的形式返回
*/
Object[] array = list1.toArray();
/**
* toArray的重载方法,可以很方便的让我们装换出实际的数组类型;
* 参数的作用是作为返回数组的类型,所有参数传入的数组不需要
* 任何的长度,因为用不到,就没必要浪费空间
*/
String[] array1 = (String[]) list1.toArray(new String[0]);
/**
* 泛型定义基本类型时使用其包装类
*/
List<Integer> list4 = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list4.add(i);
}
System.out.println(list4);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//取子集(3-7)
List<Integer> subList = list4.subList(3,8);//含头不含尾
System.out.println(subList);//[3, 4, 5, 6, 7]
/**
* 若我们对自己的元素进行修改会不会影响原来的集合?
* 注意,我们在获取子集后,若对自己元素进行修改,会影响
* 原来的集合元素。
*/
for (int i = 0; i < subList.size(); i++) {
subList.set(i,subList.get(i)*10);
}
System.out.println(subList);//[30, 40, 50, 60, 70]
System.out.println(list4);//[0, 1, 2, 30, 40, 50, 60, 70, 8, 9]
}
}
迭代器
- 所有Collection的实现类都实现了其iterator方法,该方法返回一个Iterator接口类型对象,用于实现对集合元素的迭代遍历。Iterator定义有三个方法:
- boolean hasNext();判断指针后面是否有元素
- next();指针后移,返回当前元素
- void remove(); 在原集合中删除刚刚返回的元素
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 迭代器
* 用于遍历集合中的元素使用
*/
public class IteratorTest {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("#");
list.add("2");
list.add("#");
list.add("3");
list.add("#");
/*
* iterator()方法
* 改方法会返回一个Iterator的实现类实例,用于遍历当前集合
* Iterator在java.util包下
* 其是一个接口,定义了遍历器应有的方法
* 不同集合返回的Iterator不都是同一个子类实现
* 了解即可。
* 迭代器的使用方式:先问后拿
* 问:boolean hasNext()该方法询问迭代器当前集合是否还有元素。
* 拿:Object next()该方法会获取当前元素。
* 迭代器的迭代方法是为while循环量身定制的
*/
Iterator iterator = list.iterator();
while (iterator.hasNext()){ //集合中是否还有下一个元素
Object element = iterator.next();//有就将其取出
/**
* 在迭代器迭代的过程中,我们不能通过集合的增删改等操作
* 来改变集合的元素数量!否则会引发迭代异常!
* 若想删除迭代出来的元素,只能通过Iterator
*/
if ("#".equals(element)){
//list.remove(element);//不可以这样修改集合,会引发迭代异常
/**
* 迭代器的remove()方法可以将刚刚获取的元素删除,
* 但是不能重复调用两次,因为你remove一次之后
* 当前元素已经不存在了,再次remove肯定会报错
*/
iterator.remove();//删除当前位置的元素
}
System.out.println(element);
}
System.out.println(list);
}
}
For-Each循环
java1.5的另一个特性:新循环(增强for循环)新循环的作用是专为遍历数组和集合使用的。
for(ElementType element:ArrayOrCollection){
...
}
遍历数组或集合,将每一个元素依次赋值给element后进入循环体。直到所有元素均被迭代完毕后退出循环。
import java.util.ArrayList;
import java.util.List;
/**
* For-Each循环
*/
public class ForEach {
public static void main(String[] args) {
//和常规for循环在遍历数组上的差异
int[] array = new int[]{1,2,3,4,5,6,7};
/**
* 常规循环:
* 自己维护循环次数
* 循环体从自行维护获取元素的方式
*/
for (int i = 0; i < array.length; i++) { //维护循环次数
int element = array[i];//获取数组元素
System.out.println(element);
}
/*
* For-Each循环
* 自动维护循环次数(由遍历的数组或集合的长度决定)
* 自动获取每次迭代的元素
* 该循环执行流程:
* 遍历数组array中每个元素,将元素依次赋值给element
* 后进入循环体,直到所有元素均被迭代完毕后退出循环
* 注意事项:
* 使用该循环,element的类型应与循环迭代的数组或集合
* 中的元素类型一致!至少要是兼容类型。
* 这个循环的内部实现是使用迭代器Iterator完成的。
*/
for(int element : array){
System.out.println(element);
}
List<String> list = new ArrayList<String>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
/**
* 使用ForEach循环来遍历集合
* 注意:
* 集合若使用ForEach,应该为其定义泛型,否则我们只能
* 使用Object作为接收元素
*/
for (String element : list){
System.out.println(element);
}
}
}