集合的遍历

1. list的遍历

1.普通for循环

for(int i = 0 ;i<list.size();i++) {  
    int j= (Integer) list.get(i);
    System.out.println(j);  
}

2.增强for循环

for (Object object : list) { 
    System.out.println(object); 
}

3.迭代器iterator

Iterator iterator = list.iterator();
while(iterator.hasNext()){
    int i = (Integer) iterator.next();
    System.out.println(i);
}

// 或者
for(Iterator iterator = list.iterator();iterator.hasNext();){                    
    int i = (Integer) iterator.next();                   
    System.out.println(i);               
}

4.list.forEach()方法

list.forEach(v-> System.out.println(v));

各遍历方式的适用于什么场合?
1、传统的for循环遍历,基于计数器的:
顺序存储:读取性能比较高。适用于遍历顺序存储集合。
链式存储:时间复杂度太大,不适用于遍历链式存储的集合。
2、迭代器遍历,Iterator:
顺序存储:如果不是太在意时间,推荐选择此方式,毕竟代码更加简洁,也防止了Off-By-One的问题。
链式存储:意义就重大了,平均时间复杂度降为O(n),还是挺诱人的,所以推荐此种遍历方式。
3、foreach循环遍历:
foreach只是让代码更加简洁了,但是他有一些缺点,就是遍历过程中不能操作数据集合(删除等),所以有些场合不使用。而且它本身就是基于Iterator实现的,但是由于类型转换的问题,所以会比直接使用Iterator慢一点,但是还好,时间复杂度都是一样的。所以怎么选择,参考上面两种方式,做一个折中的选择。

2.set的遍历

1.迭代器遍历:

Set<String> set = new HashSet<String>();  
Iterator<String> it = set.iterator();  
while (it.hasNext()) {  
  String str = it.next();  
  System.out.println(str);  
}  

2.增强for循环遍历:

for (String str : set) {  
      System.out.println(str);  
}  


优点还体现在泛型 假如 set中存放的是Object  

Set<Object> set = new HashSet<Object>();  
for循环遍历:  
for (Object obj: set) {  
      if(obj instanceof Integer){  
                int aa= (Integer)obj;  
             }else if(obj instanceof String){  
               String aa = (String)obj  
             }  
              ........  
}   

3. map的遍历:

1、通过获取所有的key按照key来遍历
//Set<Integer> set = map.keySet(); //得到所有key的集合
for (Integer in : map.keySet()) {
    String str = map.get(in);//得到每个key多对用value的值
}

2、通过Map.entrySet使用iterator遍历key和value
Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
     Map.Entry<Integer, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

3、通过Map.entrySet遍历key和value,推荐,尤其是容量大时
for (Map.Entry<Integer, String> entry : map.entrySet()) {
    //Map.entry<Integer,String> 映射项(键-值对)  有几个方法:用上面的名字entry
    //entry.getKey() ;entry.getValue(); entry.setValue();
    //map.entrySet()  返回此映射中包含的映射关系的 Set视图。
    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

4、通过Map.values()遍历所有的value,但不能遍历key
for (String v : map.values()) {
    System.out.println("value= " + v);
}

4. 集合嵌套综合:

ackage org.westos.Demo;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

//              基础班
//                  张三      20
//                  李四      22
//              就业班
//                  王五      21
//                  赵六      23
//       HashMap嵌套HashMap
//       HashMap嵌套ArrayList
public class ZuoYe4 {
    public static void main(String[] args) {
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("张三", 20);
        hm.put("李四", 22);
        HashMap<String, Integer> hm1 = new HashMap<>();
        hm1.put("王五", 21);
        hm1.put("赵六", 23);

        HashMap<String, HashMap<String, Integer>> HM = new HashMap<>();
        HM.put("基础班", hm);
        HM.put("就业办", hm1);
        //第一种遍历方式
        Set<String> strings = HM.keySet();
        for (String string : strings) {
            System.out.println(string);
            HashMap<String, Integer> stringIntegerHashMap = HM.get(string);

            Set<String> strings1 = stringIntegerHashMap.keySet();
            for (String st : strings1) {
                Integer integer = stringIntegerHashMap.get(st);
                System.out.println("\t" + st + "\t\t" + integer);
            }


        }
        System.out.println("--------------------------------------------");
        //第二种遍历方式
        Set<Map.Entry<String, HashMap<String, Integer>>> entries = HM.entrySet();
        for (Map.Entry<String, HashMap<String, Integer>> entry : entries) {
            String key = entry.getKey();
            System.out.println(key);
            HashMap<String, Integer> value = entry.getValue();
            Set<Map.Entry<String, Integer>> entries1 = value.entrySet();
            for (Map.Entry<String, Integer> entry1 : entries1) {
                String key1 = entry1.getKey();
                Integer value1 = entry1.getValue();
                System.out.println("\t" + key1 + "\t\t" + value1);

            }
        }
    }

4.使用集合完成扑克牌游戏:

  1. 无序版:
package org.westos.collection.poker;

import java.util.ArrayList;
import java.util.Collections;

public class Poker {

    // 3个玩家 和 底牌
    public static ArrayList<String> Jack = new ArrayList<>();
    public static ArrayList<String> Mary = new ArrayList<>();
    public static ArrayList<String> Blank = new ArrayList<>();
    public static ArrayList<String> Bottom = new ArrayList<>();


    /**
     * 生成一副牌并洗牌,ArrayList实现
     */
    public static ArrayList<String> createPoker(){

        ArrayList<String> pokerList = new ArrayList<>();
        String[] colors = {"♥", "♠", "♣", "♦"};
        String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

        for (String color : colors) {
            for (String num : nums) {
                pokerList.add(color.concat(num));
            }
        }

        //手动添加大小王
        pokerList.add("☀");
        pokerList.add("��");
        //洗牌
        Collections.shuffle(pokerList);
        Collections.shuffle(pokerList);
        Collections.shuffle(pokerList);

        return pokerList;
    }

    /**
     * 三人斗地主,发牌开始,留3张底牌
     */
    public void display(ArrayList<String> poker){
        for (int i = 0; i < poker.size(); i++) {
            if(i >= poker.size() - 3){
                Bottom.add(poker.get(i));
            }else if(i % 3 == 0){
                Jack.add(poker.get(i));
            }else if(i % 3 == 1){
                Mary.add(poker.get(i));
            }else{
                Blank.add(poker.get(i));
            }
        }
    }


    public void peekPoker(String name, ArrayList<String> poker){
        System.out.println(name + " :");
        for (String s : poker) {
            System.out.print(s + " ");
        }
        System.out.println();
    }
}

2.有序版:

package org.westos.working.collection.poker;

import java.util.*;

/**
 *  //排序版
 *         //1.思路:你要给每张牌编张索引 要用双列集合 键是Integer 值是String
 *         // 2.再创建一个索引集合,来装索引
 *         //3.洗牌 其实洗索引集合
 *         //4.发牌 发索引  每个人用TreeSet集合 能够对索引进行排序
 *         //5.看牌 键找值
 */
public class PokerImprove {

    /**
     * 3 个玩家 和 底牌
     */
    public static TreeSet<Integer> Jack = new TreeSet<>();
    public static TreeSet<Integer> Mary = new TreeSet<>();
    public static TreeSet<Integer> Blank = new TreeSet<>();
    public static TreeSet<Integer> Bottom = new TreeSet<>();

    /**
     * 扑克牌
     */
    public static Map<Integer, String> map = new HashMap<>();


    /**
     * 创建一副扑克牌,并完成洗牌
     * @return
     */
    public static ArrayList<Integer> createPoker() {

        ArrayList<Integer> list = new ArrayList<>();
        String[] colors = {"♥", "♠", "♣", "♦"};
        String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

        //定义一个索引
        int index = 0;
        for (String num : nums) {
            for (String color : colors) {
                //把生成的牌存进集合中
                map.put(index, num.concat(color));
                //顺便给索引集合里面存一份索引
                list.add(index);
                index++;
            }
        }

        //手动添加大小王
        map.put(index, "☀");
        list.add(index);
        index++;
        map.put(index, "��");
        list.add(index);

        //洗牌
        Collections.shuffle(list);
        Collections.shuffle(list);
        Collections.shuffle(list);

        return list;
    }

    /**
     * 三人斗地主,发牌开始,留3张底牌
     */
    public void display(List<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            if (i >= list.size() - 3) {
                Bottom.add(list.get(i));
            } else if (i % 3 == 0) {
                Jack.add(list.get(i));
            } else if (i % 3 == 1) {
                Mary.add(list.get(i));
            } else if (i % 3 == 2) {
                Blank.add(list.get(i));
            }
        }
    }

    /**
     * 看玩家的牌 和 底牌
     *
     * @param name
     * @param treeSet
     */
    public void peekPoker(String name, TreeSet<Integer> treeSet) {
        System.out.println(name + " :");
        for (Integer i : treeSet) {
            System.out.print(map.get(i) + " ");
        }
        System.out.println();
    }

}

测试:

package org.westos.working.collection.poker;

import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;

public class PokerTest {

    @Test
    public void testPoker() {

        //实现斗地主的发牌,洗牌,看牌,
        //思路:
        // 1.生成一副牌,放在集合(牌盒)
        //2.洗牌
        //3.三个人斗地主,留三张底牌 发牌
        //4.看牌 ,看谁拿了一副好牌

        Poker poker = new Poker();
        ArrayList<String> pokerBox = Poker.createPoker();
        poker.display(pokerBox);

        poker.peekPoker("Blank", Poker.Blank);
        poker.peekPoker("Mary", Poker.Mary);
        poker.peekPoker("Jack", Poker.Jack);
        poker.peekPoker("Bottom", Poker.Bottom);
    }

    @Test
    public void testImprovePoker(){
        PokerImprove poker = new PokerImprove();
        ArrayList<Integer> list = PokerImprove.createPoker();
        // 发牌
        poker.display(list);
        // 看牌
        poker.peekPoker("Blank", PokerImprove.Blank);
        poker.peekPoker("Mary", PokerImprove.Mary);
        poker.peekPoker("Jack", PokerImprove.Jack);
        poker.peekPoker("Bottom", PokerImprove.Bottom);
    }
}
<think>嗯,用户问的是Java集合遍历,我得先想想有哪些常见的遍历方式。首先,Java的集合框架有很多种,比如List、Set、Map这些,不同的集合可能有不同的遍历方法。常用的遍历方式应该包括迭代器、for-each循环、普通for循环,还有Java8的Stream API。对了,可能还要提到Map的遍历方式,因为Map和Collection接口不同,遍历的时候需要处理键值对。 然后,得分别给出每种遍历方式的代码示例。比如,用迭代器的话,要展示如何通过iterator()方法获取迭代器,然后使用hasNext()和next()方法遍历。for-each循环比较简单,直接写个循环语法,但要注意集合必须实现Iterable接口,所以像List和Set都可以用,但Map不行,所以Map的遍历可能需要用entrySet或者keySet转成Set再用for-each。 对于普通for循环,可能适用于List这种有索引的集合,比如ArrayList,可以通过size()和get(i)方法遍历。但像LinkedList这种用get(i)效率低,所以不推荐。这点需要说明一下。 Java 8的Stream API也是一种方式,可以用stream().forEach()方法,或者结合lambda表达式。这里要注意并行流和顺序流的区别,但一般情况下可能不需要深入,除非用户问到。 对于Map的遍历,可能需要分别处理entrySet、keySet和values。比如用entrySet遍历键值对,或者先遍历key再获取value,但后者可能会有性能问题,特别是如果多次调用get(key)的话。另外,Java8的Map.forEach方法可以用BiConsumer来简化代码。 然后,每个代码示例需要给出解释,说明适用的场景和注意事项。比如迭代器可以在遍历时安全地删除元素,而for-each循环不行,否则会抛出ConcurrentModificationException异常。普通for循环在ArrayList效率高,但在LinkedList效率低,所以要根据具体集合类型选择。可能还要提到并发修改的问题,比如在用迭代器遍历时,使用迭代器的remove方法是安全的,而直接调用集合的remove方法会导致异常。这需要在解释部分说明。 用户可能需要知道各种遍历方式的优缺点,比如性能、可读性、功能限制等。比如Stream API提供了更函数式的编程方式,适合处理集合元素的转换、过滤等操作,但可能在简单遍历时显得繁琐。 最后,根据这些内容,提出相关问题。比如遍历时删除元素的方法,各种遍历方式的效率比较,如何避免并发修改异常,Java8的其他遍历方式等。这些问题可以引导用户进一步了解集合遍历的细节和常见问题。</think>Java集合遍历主要有迭代器、增强for循环、普通for循环(仅List)、Java8+的Stream API等多种方式。以下是详细实现和说明: ### 一、List集合遍历(以ArrayList为例) 1. **迭代器遍历**(适用于所有Collection集合) ```java List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C")); Iterator<String> it = list.iterator(); while(it.hasNext()) { String item = it.next(); System.out.println(item); // 安全删除当前元素 it.remove(); } ``` **特点**:唯一支持遍历时安全删除元素的方式,通过`remove()`方法删除当前迭代元素 2. **增强for循环**(语法糖,底层使用迭代器) ```java for (String item : list) { System.out.println(item); // 直接调用list.remove()会抛出ConcurrentModificationException } ``` 3. **普通for循环**(仅适用于List) ```java for(int i=0; i<list.size(); i++) { System.out.println(list.get(i)); } ``` **注意**:LinkedList使用此方式时间复杂度为O(n²),效率极低 4. **Lambda表达式**(Java8+) ```java list.forEach(item -> System.out.println(item)); // 或方法引用 list.forEach(System.out::println); ``` ### 二、Map集合遍历(以HashMap为例) 1. **EntrySet遍历**(推荐方式) ```java Map<String, Integer> map = new HashMap<>(); map.put("A", 1); map.put("B", 2); for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } ``` 2. **KeySet遍历**(不推荐多次访问) ```java for (String key : map.keySet()) { Integer value = map.get(key); System.out.println(key + ": " + value); } ``` 3. **Java8+ forEach** ```java map.forEach((k, v) -> System.out.println(k + ": " + v)); ``` ### 三、Set集合遍历 ```java Set<String> set = new HashSet<>(Arrays.asList("X", "Y", "Z")); // 方式与List相同,但无法使用普通for循环 set.forEach(System.out::println); ``` ### 四、并发集合遍历注意事项 使用`Collections.synchronizedXXX`包装的集合或`CopyOnWriteArrayList`时,需要特别注意: - 同步集合的迭代器需要手动同步 - CopyOnWriteArrayList迭代的是集合快照,遍历过程中修改不影响迭代
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

phial03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值