Java集合类主要由两个接口(Collection和Map)派生出来:
Collection
List(子接口):有序(存入和取出的顺序一致),可以重复,有索引
Vector(实现类):
操作数据:增删,查询都很慢
Enumeration elements()
返回此向量的组件的枚举。
IO流中SequenceInputStream中用到
e.g.
Vector v = new Vector;
Enumeration en =v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
ArrayList(实现类): 替代了Vector
Set(子接口) :无序(存入和取出的顺序不一定一致),不能重复
Map:存储键值对,一次添加一对,而且要保证键的唯一性
void remove():删除集合上一次next()方法返回的元素。(若集合中有多个相同的元素,都可以删掉)
取出集合的元素代码示例:
方式一:
Iterator it=al.iterator();//获取迭代器,用于取出集合中的元素。
while(it.hasNext())
{
System.out.println(it.next());
}
//方式二:for循环结束,Iterator变量内存释放,更高效
for (Iterator it=al.iterator();it.hasNext() ; )
{
System.out.println(it.next());
}
Collection的子接口,有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素
特点:都可以操作角标。
获取:
List subList(from,to);
list特有的取出元素的方式之一
for(int x = 0; x < list.size(); x++){
System.out.println( “get:” + list.get(x));
}
List集合特有的迭代器:ListIterator(列表迭代器)
Collection的子接口,元素不可以重复,是无序的,Set接口中的方法和Collection一致
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,haseCode和equals来完成的。
如果元素的HashCode值相同,才会判断equals是否为true;
如果元素的HashCode值不同,不会调用equals。
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
//HashSet集合中添加重复元素时,返回false
System.out.println(hs.add("java01"));
System.out.println(hs.add("java01"));//未存储进去为false
import java.util.HashSet;
import java.util.Iterator;
/*
* 往HashSet集合中存入自定义对象姓名和年龄相同为同一个人,重复元素。
*/
class HashSetDemo {
public static void main(String[] args) {
System.out.println("以下为集合中元素存储的比较过程:");
HashSet hs = new HashSet();
hs.add(new Person("a1", 11));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 13));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 14));
System.out.println("去掉重复元素后的结果:");
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = it.next();
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
class Person {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 复写hashCode方法,集合底层内部调用
public int hashCode() {
System.out.println(this.name + "...hashCode");
return name.hashCode() + age * 3;// *3保证hash值的唯一性
}
// 复写equals方法
public boolean equals(Object obj) {
if (!(obj instanceof Person))
return false;
Person p = (Person) obj;
System.out.println(this.name + ":equals:" + p.name);
return this.name.equals(p.name) && this.age == p.age;// 此处equals为Object的方法.
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
运行结果:
第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。
代码示例:
import java.util.Iterator;
import java.util.TreeSet;
/**
* 需求: 往TreeSet集合中存储自定义对象学生。 年龄和姓名均相同时,视为同一个人,
* 并按照学生的年龄进行排序, 当年龄相同时,按照名字的自然顺序排序
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("C", 19));
ts.add(new Student("D", 17));
ts.add(new Student("C", 19));
ts.add(new Student("A", 20));
ts.add(new Student("E", 17));
Iterator it = ts.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.getName() + "..." + s.getAge());
}
}
}
class Student implements Comparable { // 该接口强制让学生具备比较性。
private String name;
private int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
public int compareTo(Student s) { // 内部底层调用
// 存与取的方式相同,将不能除去重复的对象元素
//return 1;
// 存与取的方式刚好相反,将不能除去重复的对象元素
// return -1;
// 按自然顺序取出
System.out.println(this.name + ":compareto:" + s.name);
if (this.age > s.age) {
return 1;
// 判断次要条件:当年龄相同时,比较姓名是否相同
} else if (this.age == s.age) {
return this.name.compareTo(s.name);// 字符串自有的比较方法。
} else
return -1;
/*简化书写
int temp = this.age - s.age;
return temp == 0? this.name.compareTo(s.name) : temp;*/
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
运行结果:
注意:如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准
代码示例:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/*
* 需求:按姓名排序,不修改compareTo方法
*/
class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new MyCompare());// 将比较器对象作为参数传递给TreeSet集合的构造函数
ts.add(new Student("A", 20));
ts.add(new Student("C", 19));
ts.add(new Student("E", 17));
ts.add(new Student("D", 17));
ts.add(new Student("A", 18));
ts.add(new Student("C", 19));
Iterator it = ts.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.getName() + "..." + s.getAge());
}
}
}
class Student implements Comparable<Student> { // 该接口强制让学生具备比较性。
private String name;
private int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
public int compareTo(Student s){ // 内部底层调用
// 按自然顺序取出
System.out.println(this.name + ":compareto:" + s.name);
int temp = this.age - s.age;
return temp == 0? this.name.compareTo(s.name) : temp;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// 定义一个类,实现Comparator接口
class MyCompare implements Comparator<Student> {
//覆盖compare方法
public int compare(Student s1, Student s2) {
int num = s1.getName().compareTo(s2.getName());
if (num == 0) {
/*//第一种方法
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
/*//第二种方法
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));*/
// 第三种方法
return s1.getAge() - s2.getAge();
}
return num;
}
}
运行结果: