您的位置:首页 > 编程语言 > Java开发

Java核心API(4) —— 集合、泛型

2018-02-01 22:36 429 查看

一、集合

  在实际开发中,需要将使用的对象存储于特定数据结构的容器中。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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: