Java 集合(1)
集合体系图:
-
List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
-
Set下有HashSet,LinkedHashSet,TreeSet
-
List下有ArrayList,Vector,LinkedList
-
Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
1、框架集合
1.1、集合介绍
我们知道数据多了就会使用数组存放。而且数组中存放的都是基本类型
的数据,并且数组是定长
的。当在程序中创建的对象比较多的时候,需要对这些对象进行统一的管理和操作,那么首先我们就需要把这些对象存储起来。使用集合
。
集合和数组的容器:
数组的长度是固定的。集合的长度是可变的。
数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。
集合作用:
当对象多的时候,先进行存储
1.2、集合框架的由来
集合本身是一个工具,它存放在java.util包中。
JDK最早的1.0版本中。提供的集合容器很少。升级到1.2版,为了更多的需求,出现了集合框架。有了更多的容器。可以完成不同的需求。
这些容器怎么区分?区分的方式:每一个容器的数据结构(数据存储到的一种方式)不一样。
不同的容器进行不断的向上抽取,最后形成了一个集合框架,这个框架就是Collection
接口。在Collection
接口定义着集合框架中最共性的内容。
1.3、Collection接口的描述
既然Collection接口是集合中的顶层接口,那么它中定义的所有功能子类都可以使用。查阅API中描述的Collection接口。Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
1.4、Collection基本方法了解
这里我们不关心具体创建的Collection中的那个子类对象,这里重点演示的是Collection接口中的方法
Collection coll = new ArrayList();
//1,往集合中添加对象元素。add(Object);
coll.add("itcast1");
coll.add("itcast2");
coll.add("itcast3");
//2,删除。
coll.remove("itcast2");
//3,判断是否包含。
System.out.println(coll.contains("itcast11"));
//4,清除。
coll.clear();
//把集合打印一下。
System.out.println(coll);//[itcast1, itcast2, itcast3]
1.5、Collection带All的方法
上个例子给大家演示Collection接口的常用方法,但是在Collection中,还有一些方法后面带有All,这些方法又是做什么的呢?
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
//1,给两个集合添加元素。
c1.add("abc1");
c1.add("abc2");
c1.add("abc3");
c2.add("abc1");
c2.add("abc4");
c2.add("abc5");
//添加所有c2的元素到c1中。
c1.addAll(c2);
boolean b = c1.containsAll(c2);
System.out.println("b="+b);
//删除c1中所有和c2相同的元素。
c1.removeAll(c2);
//保留了c1中和c2相同的元素。
c1.retainAll(c2);
//打印。
System.out.println("c1="+c1);
2、迭代器
2.1、Iterator原理
由于集合容器有很多,每个容器都有自身的数据存储结构,即每个容器自身最清楚自己中数据是如何存储的,容器这么多,每个容器数据存储又不相同,这时就在它们之间找取出元素的共性进行了抽取,抽取出集合容器取出元素的共同特点。
在取元素之前先要判断集合中有没有元素,如果有就把这个元素取出来,继续在判断,如果还有就再取出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代
。
集合中把这种取元素的方式描述在Iterator接口中。
2.2、Iterator迭代代码体现
在Collection接口描述了一个抽象方法iterator方法,所有Collection子类都实现了这个方法,并且有自己的迭代形式。
//1,创建集合对象。
Collection coll = new ArrayList();
coll.add("abc1");
coll.add("abc2");
coll.add("abc3");
coll.add("abc4");
/*//2.获取容器的迭代器对象。通过iterator方法。
Iterator it = coll.iterator();
//3,使用具体的迭代器对象获取集合中的元素。参阅迭代器的方法
while(it.hasNext()){
System.out.println(it.next());
}*/
for (Iterator it = coll.iterator(); it.hasNext();) {
System.out.println(it.next());
}
注意:在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.NoSuchElementException没有这个元素异常
3、集合的细节
3.1、集合的使用细节
在使用集合时需要注意一下几点
:
- 集合中存储其实都是对象的地址。
- 集合中可以存储基本数值吗?不行,但是jdk1.5以后可以这么写,但是存储的还是对象(基本数据类型包装类对象)。
- 存储时提升了Object。取出时要使用元素的特有内容,必须向下转型。
Collection coll = new ArrayList();
coll.add("abc");
coll.add("aabbcc");
coll.add("shitcast");
for (Iterator it = coll.iterator(); it.hasNext();) {
//由于元素被存放进集合后全部被提升为Object类型,当需要使用子类对象特有方法时,需要向下转型
String str = (String) it.next();
System.out.println(str.length());
}
注意:如果集合中存放的是多个对象,这时进行向下转型会发生类型转换异常。
3.2、集合中存放自定义对象
需要创建一个自定义类
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
pulic void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//建立学生自己的比较方式
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if(!(obj instanceof Student)){
throw new ClassCastException("类型错误");
}
Student s = (Student)obj;
return this.age == s.age && this.name.equals(s.name);
}
}
创建集合对象,存储自定义对象。
public class CollectionDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
Student s = new Student("zhangsan",21);
coll.add(s);
coll.add(new Student("lisi",22));
coll.add(new Student("wangwu",23));
for (Iterator it = coll.iterator(); it.hasNext();) {
// 由于元素被存放进集合后全部被提升为Object类型,当需要使用子类对象特有方法时,需要向下转型。
Student stu = (Student) it.next();
Sysem.out.println(stu);
}
}
}
Collection中可以存放重复的元素,也可以存放不重复的元素。什么是重复的元素呢。这里给大家说明下,在给集合中存放对象时,集合中的所有对象有自己的方法比较是不是同一元素。一般情况都是使用equals
方法,而所有对象都是Ojbect类的孩子,所以都会继承到Object中的equals方法。而Object中的equals方法是比较的是两个对象的内存地址是否相同,而在开发的时候我们需要根据对象的自身数据建立属于对象特有的比较方法,这时我们需要复写equals方法。