疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java集合【迭代器、增强for、泛型】


 

   

  java.util.Collection接口

  是集合的最顶层的接口,定义了集合共性的方法

  接口无法直接创建对象,使用多态的方式创建对象

  Collection<集合中的数据类型(泛型)> coll = new ArrayList<集合中的数据类型(泛型)>();

  迭代器

  集合中存储数据的方式(数据类型)不一样,取出集合中元素的方式也不同,java给我们提供了一种公共的取出元素的方式,叫迭代器

  描述迭代器的接口:java.util.Iterator

  接口中的抽象方法:

  boolean hasNext() 如果仍有元素可以迭代,则返回 true。 判断集合中还有没有元素,有返回true,没有返回false

  E next() 返回迭代的下一个元素。 取出集合中的下一个元素

  迭代器是一个接口,需要找到迭代器的实现类,迭代器的实现类是每个集合的内部类

  在Collection接口中有一个方法: iterator方法返回的就是迭代器

  Iterator iterator() 返回在此 collection 的元素上进行迭代的迭代器。

  ArrayList集合实现了Collection接口,重写iterator方法,方法的返回值就是迭代器的实现类对象

  注意:我们只需要知道iterator方法返回的而是迭代器的实现类就行了,不需要关注返回的是哪个实现类对象,这种变成方式叫做面向接口编程

  迭代器的使用步骤:

  1.创建集合对象,往集合中添加元素

  2.使用集合中的方法iterator获取迭代器的实现类对象,使用Iterator接口接收(多态)

  3.使用iterator中的方法hasNext和next方法进行迭代,取出集合中的元素

  复制代码

  1 public static void main(String[] args) {

  2 //1.创建集合对象,往集合中添加元素

  3 //Collection coll = new ArrayList();

  4 Collection coll = new HashSet();

  5 coll.add("姚明");

  6 coll.add("乔丹");

  7 coll.add("詹姆斯");

  8 coll.add("科比");

  9 coll.add("艾弗森");

  10 //2.使用集合中的方法iterator获取迭代器的实现类对象,使用Iterator接口接收(多态)

  11 //集合中的数据类型是什么,迭代器的数据类型就是什么,跟着集合走

  12 Iterator it = coll.iterator();

  13 //3.使用iterator中的方法hasNext和next方法进行迭代,取出集合中的元素

  14 //boolean hasNext() 如果仍有元素可以迭代,则返回 true。

  15 /*boolean b = it.hasNext();

  16 System.out.println(b);

  17 //E(String) next() 返回迭代的下一个元素。

  18 String s = it.next();

  19 System.out.println(s);

  20

  21 b = it.hasNext();

  22 System.out.println(b);

  23 s = it.next();

  24 System.out.println(s);

  25

  26 b = it.hasNext();

  27 System.out.println(b);

  28 s = it.next();

  29 System.out.println(s);

  30

  31 b = it.hasNext();

  32 System.out.println(b);

  33 s = it.next();

  34 System.out.println(s);

  35

  36 b = it.hasNext();

  37 System.out.println(b);

  38 s = it.next();

  39 System.out.println(s);

  40

  41 b = it.hasNext();

  42 System.out.println(b);//false,没有元素了

  43 s = it.next();//没有元素了,在取就报NoSuchElementException没有元素异常

  44 System.out.println(s);*/

  45

  46 /*

  47 * 发现以上迭代的过程是一个重复的过程,可以使用循环优化

  48 * 我们不知道集合中有多少元素,所以可以使用while循环

  49 * while循环的结束条件:hasNext();返回false

  50 */

  51 while(it.hasNext()){

  52 String s = it.next();

  53 System.out.println(s);

  54 }

  55 System.out.println("-------------------");

  56 /*

  57 * for循环方式迭代器,使用不多

  58 */

  59 /*for(Iterator it2 = coll.iterator();it2.hasNext();){

  60 String s = it2.next();//取出元素,移动指针到下一位

  61 System.out.println(s);

  62 }*/

  63 }

  复制代码

  并发修改异常

  在迭代的过程中,对集合的长度进行了修改,就会发生并发修改异常

  遍历的过程中,集合的长度进行了修改,但是迭代器并不知道,就会产生ConcurrentModificationException

  解决方法:

  1.迭代就是迭代,不要对集合进行修改

  2.使用迭代器Iterator的子接口ListIterator中的方法add/remove,让迭代器自己增加往集合中增加元素/移除元素

  这样迭代器本身知道了集合的变化,就不会产生并发修改异常了

  void add(E e) 将指定的元素插入列表(可选操作)。

  void remove() 从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。

  复制代码

  1 public static void main(String[] args) {

  2 ArrayList list = new ArrayList();

  3

  4 list.add(null);

  5 list.add("abc1");

  6 list.add("abc2");

  7 list.add("abc3");

  8 list.add("abc4");

  9

  10 /*

  11 * 使用迭代器遍历集合

  12 */

  13 //获取迭代器

  14 Iterator it = list.iterator();

  15 //使用while遍历集合

  16 while(it.hasNext()){

  17 String s = it.next();

  18

  19 /*

  20 * 判断集合中有没有"abc3"这个元素

  21 * 如果有,增加一个元素"itcast"

  22 * 编程技巧:使用equals判断的时候,要把已知的变量写在前边,未知的写在后边,防止空指针异常

  23 */

  24 //if(s.equals("abc3")){

  25 if("abc3".equals(s)){

  26 //1.迭代就是迭代,不要对集合进行修改

  27 //list.add("itcast");

  28 }

  29

  30 System.out.println(s);

  31 }

  32

  33 System.out.println("------------------");

  34

  35 /*

  36 * 2.使用迭代器Iterator的子接口ListIterator中的方法add/remove,让迭代器自己增加往集合中增加元素/移除元素

  37 */

  38 ListIterator listIt = list.listIterator();

  39 while(listIt.hasNext()){

  40 String s = listIt.next();

  41 if("abc3".equals(s)){

  42 listIt.add("itcast");

  43 }

  44 System.out.println(s);

  45 }

  46 System.out.println(list);

  47 }

  复制代码

  增强for

  内部是一个迭代器,简化了迭代的代码,使遍历更加简单

  Collection接口继承Iterable,所以Collection接口的所有实现类都可以是用增强for

  注意:增强for是JDK1.5之后出现的

  格式:

  for(数据类型(集合/数组的数据类型) 变量名 : 集合名/数组名){

  syso(变量名);

  }

  Java中的泛型

  就是数据类型,在创建对象的时候确定

  Java中的泛型是一个伪泛型:在编译的时候有(写代码.java中),运行的时候(.class)没有

  随机数:伪随机数

  泛型的好处:

  1.避免强转,可以直接使用元素特有的方法

  2.把运行期的异常,转换编译期异常(编译失败)

  定义含有泛型的类

  模仿ArrayList集合

  public class ArrayList{}

  E:是一个未知的数据类型,可能是Integer,可能是String,可能Person

  创建类对象的时候确定数据类型

  定义格式:

  修饰符 class 类名{

  }

  复制代码

  1 public class GenericClass {

  2 private E name;

  3

  4 public E getName() {

  5 return name;

  6 }

  7

  8 public void setName(E name) {

  9 this.name = name;

  10 }

  11

  12 public void method(E e){

  13 System.out.println(e);

  14 }

  复制代码

  定义含有泛型的接口

  格式:

  修饰符 interface 接口名<泛型>{

  抽象方法(参数<泛型>);

  }

  1 public interface GenericInterface {

  2 public abstract void method(E e);

  3 }

  复制代码

  1 /*

  2 * 1.定义接口的实现类,不管泛型,接口泛型是怎么写的,实现类也怎么写

  3 * public class ArrayList implements List{}

  4 * 创建实现类对象的时候确定泛型的数据类型

  5 */

  6 class GenericInterfaceImpl1 implements GenericInterface{

  7

  8 @Override

  9 public void method(E e) {

  10 System.out.println(e);

  11 }

  12 }

  复制代码

  含有泛型的方法

  不是类上定义的泛型,是方法自己定义的泛型

  定义格式:在修饰符和返回值类型之间要定义泛型,才能使用

  修饰符 <泛型> 返回值类型 方法名(参数<泛型>){

  }

  方法上的泛型,在调用方法的时候确定数据类型,传递的是什么类型的数据,泛型就是什么类型(和类上的泛型没有关系)

  复制代码

  1 public class GenericMethod {

  2

  3 /*

  4 * 定义方法,使用类上的泛型

  5 */

  6 public void method(E e){

  7 System.out.println(e);

  8 }

  9

  10 /*

  11 * 定义一个含有泛型的方法

  12 */

  13 public void function(T t){

  14 System.out.println(t);

  15 }

  复制代码

  泛型的通配符:?,代表任意的数据类型

  上限限定:? extends E代表只要是E类型的子类即可

  下限限定:? super E代表只要是E类型的父类即可

  ArrayList集合的构造方法

  ArrayList(Collection c)

  参数是一个集合,集合的数据类型有要求,只能是ArrayList泛型的子类或者是本身

  ArrayList(Collection c)

  参数是一个集合,集合的数据类型有要求,只能是ArrayList泛型的子类或者是本身

  复制代码

  1 /*

  2 * 斗地主案例:

  3 * 1.准备牌

  4 * 2.洗牌

  5 * 3.发牌

  6 * 4.看牌

  7 */

  8 public class DouDiZhu {

  9 public static void main(String[] args) {

  10 //1.准备牌

  11 //创建存储54张牌的集合

  12 ArrayList poker = new ArrayList();

  13 //存储大王小王

  14 poker.add("大王");

  15 poker.add("小王");

  16 //存储52张牌

  17 //创建序号的数组

  18 String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};

  19 //创建花色数组

  20 String[] colors = {"?","?","?","?"};

  21 //嵌套遍历两个数组

  22 for (String number : numbers) {

  23 for (String color : colors) {

  24 //System.out.println(color+number);

  25 //把组合的牌放入到集合中

  26 poker.add(color+number);

  27 }

  28 }

  29 //System.out.println(poker);

  30

  31 /*

  32 * 2.洗牌

  33 * 使用Collections中的方法

  34 * static void shuffle(List list)

  35 */

  36 Collections.shuffle(poker);

  37 //System.out.println(poker);

  38

  39 /*

  40 * 3.发牌

  41 * 创建4个集合

  42 * 遍历poker集合

  43 * 使用poker集合的索引%3发牌

  44 */

  45 ArrayList player01 = new ArrayList();

  46 ArrayList player02 = new ArrayList();

  47 ArrayList player03 = new ArrayList();

  48 ArrayList diPai = new ArrayList();

  49 //遍历poker集合

  50 for (int i = 0; i < poker.size(); i++) {

  51 //获取牌

  52 String s = poker.get(i);

  53 //先判断索引是否为底牌的索引 51 52 53

  54 if(i >=51){

  55 //给底牌发牌

  56 diPai.add(s);

  57 }else if(i%3==0){

  58 //给玩家1发牌

  59 player01.add(s);

  60 }else if(i%3==1){

  61 //给玩家1发牌

  62 player02.add(s);

  63 }else if(i%3==2){

  64 //给玩家1发牌

  65 player03.add(s);

  66 }

  67 }

  68 //4.看牌

  69 System.out.println("刘德华:"+player01);

  70 System.out.println("周润发:"+player02);

  71 System.out.println("周星驰:"+player03);

  72 System.out.println("底牌:"+diPai);

  73 }

  74 }