1.List
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
与 set 不同,列表通常允许重复的元素。更确切地讲,列表通常允许满足 e1.equals(e2) 的元素对 e1 和 e2,并且如果列表本身允许 null 元素的话,通常它们允许多个 null 元素。难免有人希望通过在用户尝试插入重复元素时抛出运行时异常的方法来禁止重复的列表,但我们希望这种用法越少越好。
List 接口在 iterator、add、remove、equals 和hashCode 方法的协定上加了一些其他约定,超过了 Collection 接口中指定的约定。为方便起见,这里也包括了其他继承方法的声明。
List 接口提供了 4 种对列表元素进行定位(索引)访问方法。列表(像 Java 数组一样)是基于 0 的。注意,这些操作可能在和某些实现(例如LinkedList 类)的索引值成比例的时间内执行。因此,如果调用者不知道实现,那么在列表元素上迭代通常优于用索引遍历列表。
List 接口提供了特殊的迭代器,称为 ListIterator,除了允许 Iterator 接口提供的正常操作外,该迭代器还允许元素插入和替换,以及双向访问。还提供了一个方法来获取从列表中指定位置开始的列表迭代器。
方法摘要:
boolean | add(E e) 向列表的尾部添加指定的元素(可选操作)。 | |
void | add(int index,E element) 在列表的指定位置插入指定元素(可选操作)。 | |
boolean | addAll(Collection<? extendsE> c) 添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。 | |
boolean | addAll(int index,Collection<? extendsE> c) 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。 | |
void | clear() 从列表中移除所有元素(可选操作)。 | |
boolean | contains(Object o) 如果列表包含指定的元素,则返回 true。 | |
boolean | containsAll(Collection<?> c) 如果列表包含指定 collection 的所有元素,则返回 true。 | |
boolean | equals(Object o) 比较指定的对象与列表是否相等。 | |
E | get(int index) 返回列表中指定位置的元素。 | |
int | hashCode() 返回列表的哈希码值。 | |
int | indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 | |
boolean | isEmpty() 如果列表不包含元素,则返回 true。 | |
Iterator<E> | iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器。 | |
int | lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。 | |
ListIterator<E> | listIterator() 返回此列表元素的列表迭代器(按适当顺序)。 | |
ListIterator<E> | listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。 | |
E | remove(int index) 移除列表中指定位置的元素(可选操作)。 | |
boolean | remove(Object o) 从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。 | |
boolean | removeAll(Collection<?> c) 从列表中移除指定 collection 中包含的其所有元素(可选操作)。 | |
boolean | retainAll(Collection<?> c) 仅在列表中保留指定 collection 中所包含的元素(可选操作)。 | |
E | set(int index,E element) 用指定元素替换列表中指定位置的元素(可选操作)。 | |
int | size() 返回列表中的元素数。 | |
List<E> | subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 | |
Object[] | toArray() 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)。 | |
| toArray(T[] a) 返回按适当顺序(从第一个元素到最后一个元素)包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 |
一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2)
的元素对 e1
和e2
,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对 Set 接口进行了修改,但是没有包含任何其他的规定)。
对这些构造方法的其他规定是(不要奇怪),所有构造方法必须创建一个不包含重复元素的 set(正如上面所定义的)。
注:如果将可变对象用作 set 元素,那么必须极其小心。如果对象是 set 中某个元素,以一种影响 equals 比较的方式改变对象的值,那么 set 的行为就是不确定的。此项禁止的一个特殊情况是不允许某个 set 包含其自身作为元素。
某些 set 实现对其所包含的元素有所限制。例如,某些实现禁止 null 元素,而某些则对其元素的类型所有限制。试图添加不合格的元素会抛出未经检查的异常,通常是NullPointerException 或 ClassCastException。试图查询不合格的元素是否存在可能会抛出异常,也可能简单地返回 false;某些实现会采用前一种行为,而某些则采用后者。概括地说,试图对不合格元素执行操作时,如果完成该操作后不会导致在 set 中插入不合格的元素,则该操作可能抛出一个异常,也可能成功,这取决于实现的选择。此接口的规范中将这样的异常标记为“可选”。
方法摘要 | ||
---|---|---|
boolean | add(E e) 如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。 | |
boolean | addAll(Collection<? extendsE> c) 如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。 | |
void | clear() 移除此 set 中的所有元素(可选操作)。 | |
boolean | contains(Object o) 如果 set 包含指定的元素,则返回 true。 | |
boolean | containsAll(Collection<?> c) 如果此 set 包含指定 collection 的所有元素,则返回 true。 | |
boolean | equals(Object o) 比较指定对象与此 set 的相等性。 | |
int | hashCode() 返回 set 的哈希码值。 | |
boolean | isEmpty() 如果 set 不包含元素,则返回 true。 | |
Iterator<E> | iterator() 返回在此 set 中的元素上进行迭代的迭代器。 | |
boolean | remove(Object o) 如果 set 中存在指定的元素,则将其移除(可选操作)。 | |
boolean | removeAll(Collection<?> c) 移除 set 中那些包含在指定 collection 中的元素(可选操作)。 | |
boolean | retainAll(Collection<?> c) 仅保留 set 中那些包含在指定 collection 中的元素(可选操作)。 | |
int | size() 返回 set 中的元素数(其容量)。 | |
Object[] | toArray() 返回一个包含 set 中所有元素的数组。 | |
| toArray(T[] a) 返回一个包含此 set 中所有元素的数组;返回数组的运行时类型是指定数组的类型。 |
ListTestDemo:简单测试基本操作
package ListDemo;
public class ListTestDemo {
public static void main(String[] args) {
CourseList cou = new CourseList();
Course course1 = new Course("1","C语言");
Course course2 = new Course("2","数据结构");
Course course3 = new Course("3","离散数学");
Course course4 = new Course("4","Java程序设计");
cou.addCourse(course1);
cou.addCourse(course2);
Course [] course={course3,course4};
cou.addCourse(course); cou.testIterator();//迭代器方法遍历集合元素
cou.deleteCourse(course1);
cou.deleteAll(course);
cou.printAll();
//查看courseList中是否包含某一门课程
System.out.println("备选课程中是否包含:"+course2.getCouName()+","+cou.testContains(course2));
//创建新课程
Course course5 = new Course(course2.getCouID(), course2.getCouName());
System.out.println("备选课程中是否包含新课程:"+course5.getCouName()+","+cou.testContains(course5));
//因为虽然course2余course2有着相同的ID和名称,但是course2和course5是不同的对象,而courses中并没有course5对象
//所以返回false,由于contains方法是通过调用course的equals方法进行判断的,故要解决这个问题可以重写course的equals
//方法
}
}
SetTest :
package ListDemo;
import java.util.Scanner;
public class SetTest {
public static void main(String[] args) {
//添加备选课程
CourseList courses = new CourseList();
Course course1 = new Course("1","C语言");
Course course2 = new Course("2","数据结构");
Course course3 = new Course("3","离散数学");
Course course4 = new Course("4","Java程序设计");
Course cou[] = {course1,course2,course3,course4};
courses.addCourse(cou);
courses.printAll();
//创建学生对象
Student stu = new Student("20145104011", "小明");
System.out.println("欢迎"+stu.getStuID()+","+stu.getStuName()+"同学选课!");
Scanner sc = new Scanner(System.in);
for(int i=0;i<3;i++)
{
System.out.println("输入要选课程代码:");
String id = sc.next();
for(Course temp:courses.getCourses())
if(id.equals(temp.getCouID())) stu.getCourses().add(temp);
}
System.out.println("选择了以下"+stu.getCourses().size()+"门课程:\n"+"课程代码\t"+"课程名称");
for(Course temp:stu.getCourses()){
System.out.println(temp.getCouID()+" \t"+temp.getCouName());
}
//判断所选课程是否包含某一门课
System.out.println("输入一门课程名称:");
String name = sc.next();
Course newCourse = new Course(null, name);
System.out.println("所选课程是否包含"+name+":"+
stu.getCourses().contains(newCourse));
//由于在定义stu.courses时,是由hashset实现的set接口,而hashset的contains方法是通过调用
//equals方法和ghashCode方法实现的,当两个方法都返回true,contains方法才返回true,故要
//解决这个问题可以重写Course类的equals和hashCode方法
System.out.println("课程"+name+"在备选课程集合的位置为:"+courses.getCourses().indexOf(newCourse));
}
}
CourseList:课程集合
package ListDemo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CourseList {
private List<Course> courses;
public CourseList(){
courses=new ArrayList<Course>();
}
//添加一门课程
public void addCourse(Course course){
courses.add(course);
course=courses.get(courses.size()-1);//输出课程信息
System.out.println("成功添加课程"+course.getCouID()+":"+course.getCouName());
}
//添加多门课程
public void addCourse(Course []course){
courses.addAll(Arrays.asList(course));
for(int i=courses.size()-course.length;i<courses.size();i++){
Course temp=courses.get(i);
System.out.println("成功添加课程"+temp.getCouID()+":"+temp.getCouName());
}
}
//删除一门课程
public void deleteCourse(Course course){
for(Course temp:courses){
if(temp.equals(course)){
courses.remove(temp);
System.out.println("成功删除课程"+temp.getCouID()+":"+temp.getCouName()+"!!");
return ;
}
}
System.out.println("该课程不存在!!");
}
//删除多门课程
public void deleteAll(Course []course){
courses.removeAll(Arrays.asList(course));
}
//打印集合所有元素
public void printAll(){
System.out.println("课程编号\t"+" "+"课程名称");
for(Course course:courses)
{
System.out.println(course.getCouID()+" \t"+course.getCouName());
}
} //通过迭代器遍历
public void testIterator(){
Iterator<Course>it = courses.iterator();
Course course;
System.out.println("课程编号\t"+" "+"课程名称");
while(it.hasNext()){
course = it.next();
System.out.println(course.getCouID()+" \t"+course.getCouName());
}
}
//集合是否包含某一课程
public boolean testContains(Course course){
if(courses.contains(course))
return true;
return false;
}
//返回课程集合
public List<Course> getCourses() {
return courses;
}
}