一、集合
在实际开发中,需要将使用的对象存储于特定数据结构的容器中。JDK提供了这样的容器——集合(Collection)。
Collection是一个接口,定义了集合相关的操作方法,其有两个子接口:List和Set,List是可重复集,Set是不可重复集,元素是否重复,取决于元素的equals的比较结果。
集合中存储的都是引用类型元素,并且集合只保存每个元素对象的引用,而并非将元素对象本身存入集合。
1.1、add()
boolean add(E e),该方法会将给定的元素添加进集合,若添加成功则返回true,否则返回false。
1.2、size()
int size(),该方法用于返回当前集合中的元素总数。
1.3、clear()
void clear(),该方法用于清空当前集合。
1.4、isEmpty()
boolean isEmpty(),该方法用于判断当前集合中是否不包含任何元素。
package day03;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection c = new ArrayList();
/*
* boolean add(E e)
* 向集合中添加元素。
* 当元素成功添加到集合后返回true。
*/
c.add("one");
c.add("two");
c.add("three");
System.out.println(c);
/*
* int size()
* 返回当前集合的元素个数
*/
System.out.println("size:"+c.size());
/*
* 判断当前集合是否不含有任何元素
* 空集合
*/
boolean isEmpty = c.isEmpty();
System.out.println("是否是空集:"+isEmpty);
/*
* void clear()
* 清空集合元素
*/
System.out.println("清空集合");
c.clear();
System.out.println("size:"+c.size());
System.out.println("是否是空集:"+c.isEmpty());
}
}
1.5、contains()
boolean contains(Object o),该方法会用于判断给定的元素是否被包含在集合中,若包含则返回true,否则返回false。
这里需要注意的是,集合在判断元素是否被包含在集合中是根据每个元素的equals方法进行比较后的结果。所以通常有必要重写equals()保证contains()方法的合理结果。
public void testContains(){
Collection cells = new ArrayList();
cells.add(new Cell(1,2));
cells.add(new Cell(1,3));
cells.add(new Cell(1,4));
Cell cell = new Cell(1,3);
boolean flag = cells.contains(cell);
//如果Cell不重写equals方法将为false
System.out.println(flag);//true
}
1.6、remove()
boolean remove(E e),从集合中删除指定元素,删除成功返回true。
package day04;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1(){
public static void main(String[] args){
Collection c = new ArrayList();
c.add(new Point(1,2));
c.add(new Point(3,4));
c.add(new Point(5,6));
System.out.println(c);
Point p = new Point(1,2);
c.remove(p);
System.out.println("删除完毕");
System.out.println(c);
}
}
1.7、addAll()、containsAll()、removeAll()
package day04;
import java.util.ArrayList;
import java.util.Collection;
/**
*集合的批量操作
*/
public class CollectionDemo2{
public static void main(String[] args){
Collection c1 = new ArrayList();
c1.add("java");
c1.add("c++");
c1.add(".net");
System.out.println(c1);
Collection c2 = new HashSet();
c2.add("ios");
c2.add("android");
c2.add("linux");
c2.add("ios");
System.out.println(c2);
/*
*取并集
*boolean addAll(Collection c)
*将给定集合中的所有元素添加到当前集合中,添加后只要当前集合元素
*数量发生了变化,则返回true
*/
boolean flag = c1.addAll(c2);
System.out.println(c1);
System.out.println(flag);
Collection c3 = new ArrayList();
c3.add("java");
c3.add("android");
/*
*boolean containsAll(Collection c)
*判断当前集合是否包含给定集合中的所有元素
*/
boolean contains = c1.containsAll(c3);
System.out.println("全包含:"+contains);
/*
*从c1集合中删除两个集合中共有的元素
* remove方法会使用给定元素与集合中
* 每一个元素顺序比较equals的结果
* 并删除"第一个"与给定元素equals比较结果为true的
*/
c1.removeAll(c3);
System.out.println(c1);
}
}
二、Iterator(迭代器)
2.1、Iterator
迭代器用于遍历集合元素。获取迭代器可以使用Collection定义的方法:Iterator iterator()。迭代器Iterator是一个接口,集合在重写Collection的iterator()方法时利用内部类提供了迭代器的实现。
Iterator提供了统一的遍历集合元素的方式,其提供了用于遍历集合的两个方法:
1、boolean hasNext():判断集合是否还有元素可以遍历。
2、E next():返回迭代的下一个元素。
在使用迭代器遍历集合时,不能通过集合的remove方法删除原集合中元素,否则会抛出并发更改异常。我们可以通过迭代器自身提供的void remove()方法来删除通过next()迭代出的元素。需要注意的是,在调用remove方法前必须通过迭代器的next()方法迭代过元素,那么删除的就是这个元素,并且不能再次调用remove方法,除非再次调用next()后方可再次调用。
package day03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 使用迭代器遍历集合
* @author Administrator
*/
public class CollectionDemo8 {
public static void main(String[] args){
Collection c = new ArrayList();
c.add("one");
c.add("***");
c.add("two");
c.add("***");
c.add("three");
c.add("***");
c.add("four");
c.add(null);
//java.util.Iterator
/*
* 使用迭代器遍历集合的步骤
* 必须遵循:
* 问取删 其中删除操作不是必须的
*/
Iterator it = c.iterator();
while(it.hasNext()){
Object o = it.next();
String str = (String)o;
if("***".equals(str)){
/*
* 在迭代器遍历的过程中不能通过
* 集合的remove删除元素,只能通过
* 迭代器提供的remove方法,删除
* 刚刚next()出来的元素,并且在
* 下一次next()方法调用后,方可再次
* 调用remove()
*/
//c.remove(str);
it.remove();
}
System.out.println(str);
}
System.out.println(c);//[one,two,three,four]
}
}
2.2、for each新循环
Java 5.0之后推出了一个新的特性,增强for循环,也称为新循环。该循环不通用于传统循环的工作,其只用于遍历集合或数组。语法:
for(元素类型 e:集合或数组){
循环体
}
新循环并非新的语法,而是在编译过程中,编译器会将新循环转换为迭代器模式,所以新循环本质上是迭代器。
package day04;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class NewForDemo2{
public static void main(String[] args){
Collection c = new ArrayList();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
c.add("#");
System.out.println(c);
/*
*使用新循环遍历集合时,编译器会将它改为迭代器方式遍历。所以在使
*用新循环遍历集合时,不能通过集合的方法增删元素。
*/
for (Object o:c){
//Iterator it = c.iterator();
//while (it.hasNext()){
//Object o = it.next();
String str = (String)o;
System.out.println(str);
if ("#".equals(str)){
c.remove(str);
}
}
}
}
三、泛型机制
泛型是Java 5.0后引入的特性,泛型的本质是参数换类型。在类、接口或方法的定义过程中,所操作的数据类型被传入的参数指定。
Java泛型机制广泛的应用在集合框架中,所有的集合类型都带有泛型参数,这样在创建集合时可以指定放入集合中元素的类型。Java编译器可以据此进行类型检查,这样可以减少代码在运行时出现错误的可能性。
package day04;
public class Point<T>{
private T x;
private T y;
public Point(T x,T y){
super();
this.x = x;
this.y = y;
}
public T getX(){
return x;
}
public void setX(T x){
this.x = x;
}
public T getY(){
return y;
}
public void setY(T y){
this.y = y;
}
public String toString(){
return "("+x+","+y+")";
}
}
package day04;
public class TestPoint{
public static void main(String[] args){
Point<Integer> p1 = new Point<Integer>(1,2);
p1.setX(2);
int x1 = p1.getX();
System.out.println("x1:"+x1);
Point<Double> p2 = new Point<Double>(1.1,2.2);
p2.setX(2.2);
double x2 = p2.getX();
System.out.println("x2:"+x2);
Point<String> p3 = new Point<String>("一","二");
p3.setX("二");
String x3 = p3.getX();
System.out.println("x3:"+x3);
}
}
package day04;
/**
*泛型的原型是Object
*定义了泛型只是编译器在做一些验证工作。
*当我们对泛型类型设置值时,会检查是否满足类型要求。
*当我们获取一个泛型类型的值时,会自动进行类型转换。
*/
public class TestPoint2{
public static void main(String[] args){
/*
*这里指定泛型的实际类型为Integer,但实际上,创建的Point对象中
*,x,y属性是Object类型,这里只是应当将它当做Integer看待。
*/
Point<Integer> p1 = new Point<Integer>(1,2);
/*
*由于参数是T,这里会验证实参是否为Integer,若不是,则编译失败
*。可以传入基本类型,因为还会自动装箱。
*/
p1.setX(1);
/*
*获取时,也会自动进行造型。这里无需显示的把Object类型转换
*为Integer类型。
*/
int x1 = p1.getX();
/*
*若不指定泛型,则使用默认的Object类型。
*/
Point p2 = p1;
p2.setX("一");
String x2 = (String)p2.getX();
System.out.println("x2:"+x2);
//类造型异常
x1 = p1.getX();
System.out.println("x1:"+x1);
}
}
package day04;
import java.util.ArrayList;
import java.util.Collection;
/**
* 泛型在集合中的作用是约束集合元素类型的。
* @author Administrator
*
*/
public class TypeDemo {
public static void main(String[] args){
Collection<String> c = new ArrayList<String>();
//只能添加String类型的元素了
c.add("one");
c.add("two");
c.add("three");
for(String str : c){
System.out.println(str);
}
/*
*迭代器也应当指定泛型,而泛型的实际类型应当与它遍历的集合的泛型
*类型一致。
*/
Iterator<String> it = c.iterator();
while(it.hasNext()){
//获取元素时不需要再造型了
String str = it.next();
System.out.println(str);
}
}
}