Java集合(十): 集合遍历

x33g5p2x  于2021-09-22 转载在 Java  
字(5.7k)|赞(0)|评价(0)|浏览(828)

1、直接打印集合对象

1.1、打印 list 对象

List<Integer> list2 = Arrays.asList(1,2,3);
System.out.println(list2); // 打印出 [1, 2, 3]
System.out.println(list2.toString()); // 打印出 [1, 2, 3]

运行原理:

1、打印的是list.toString(),根据“编译看左面,运行看右面”,运行期方法的动态分派,所以执行的是ArrayList类的toString()方法。
2、ArrayList继承AbstractList

3、AbstractList继承AbstractCollention

4、AbstractCollention中重写了toString()方法

public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);// 这里是一个递归的过程
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

注意到AbstractCollection的toString方法中有一个递归的过程,当集合中嵌套集合时,打印内部集合是调用toString() 比如下面的代码:

public static void main(String[] args) {

        List list = new ArrayList();
        list.add(0);
        list.add(1);
        List list1 = new ArrayList();
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list.add(list1);
       System.out.println(list); // 输出[0, 1, [2, 3, 4]]
 }

this表示调用该方法的对象,当一个集合类的泛型是其自身,并且把自己添加到自己的集合中,就会打印 “this Collection”。

ArrayList<ArrayList> a=new ArrayList<ArrayList>();
a.add(a);
System.out.println(a.toString());
[(this Collection)]

打印集合对象

     List list = new ArrayList();
     System.out.println(list.toString());
     list.add(new User("xiaowang",3));
     list.add(new User("xiaoli",1));
[com.sankuai.payrc.demo.User5@6f94fa3e, com.sankuai.payrc.demo.User5@5e481248]
[1, 2]

原理:

最终打印的还是对象自己的toString()

public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

 @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

1.2、打印Set对象

Set set = new HashSet();
 set.add(1);
 set.add(2);
  System.out.println(set.toString());[1, 2]

运行原理:

1、打印的是list.toString(),根据“编译看左面,运行看右面”,运行期方法的动态分派,所以执行的是HashSet类的toString()方法。

2、HashSet继承AbstractSet

3、AbstractSet继承AbstractCollention

4、AbstractCollention中重写了toString()方法

public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

1.3、打印Map对象

Map<Integer,User5> map = new HashMap<>();
        map.put(1,new User5("xiaowang",3));
        map.put(2,new User5("xiaoli",1));
        System.out.println(map.toString());
{1=com.sankuai.payrc.demo.User5@4dc63996, 2=com.sankuai.payrc.demo.User5@d716361}

运行原理:

1、打印的是map.toString(),根据“编译看左面,运行看右面”,运行期方法的动态分派,所以执行的是HashMap类的toString()方法。

2、HashMap继承AbstractMap

3、AbstractMap重写了toString()

public String toString() {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (! i.hasNext())
            return "{}";

        StringBuilder sb = new StringBuilder();
        sb.append('{');
        for (;;) {
            Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key);
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value);
            if (! i.hasNext())
                return sb.append('}').toString();
            sb.append(',').append(' ');
        }
    }

1.4、数组对象

String[] s = new String[5];
        s[0] = "a";
        s[0] = "b";
        s[0] = "c";
        System.out.println(s.toString());
//[Ljava.lang.String;@6ff3c5b5
原理:
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

 总结:

  •  list、set输出基本格式:[1, 2, 3]
  •  map输出基本格式 [1="a", 2="b", 3="c"]
  • 数组输出基本格式: xxx@xxx

2、集合遍历方式

2.1、List遍历

1、Iterate()迭代器方式(collection 集合共有方法)

for(Iterator<String>    it    =    list.iterator();    it.hasNext();    )    {   
       ....   
   }   
   这种方式在循环执行过程中会进行数据锁定, 性能稍差。如果想在遍历中去掉某个元素,只能调用it.remove方法,不能使用list.remove方法,否则一定出现并发访问的错误。

2、增强for

for(String   data    :    list)    {   
       .....   
   }   
   内部调用第一种,比Iterator 慢,这种循环方式还有其他限制, 不建议使用它。

3、普通fori 方式遍历i

for(int    i=0;    i<list.size();    i++)    {   
       A    a    =    list.get(i);   
       ...   
   }   
   内部不锁定,效率最高,但是当写多线程时要考虑并发操作的问题。

List<Integer> list2 = Arrays.asList(1,2,3);
        //1、直接打印
        System.out.println(list2); // 打印出 [1, 2, 3]
        //2、iterator
        for (Iterator i = list2.iterator();i.hasNext(); ) {
            System.out.print(i.next());//123
        }
        //3、for
        for (int i = 0; i < list2.size(); i++) {
            System.out.print(list2.get(i));//123
        }
        //4、增强for
        for (Integer i: list2) {
            System.out.print(i);//123
        }

Java8中:

4、forEach() 

//foreach 最慢不推荐 java8 lambda
list.forEach(item -> System.out.println(item));

5、stream().forEach() 

list.stream().forEach(item -> System.out.println(item));

6、parallelStream().forEach() 

list.parallelStream().forEach(item -> System.out.println(item));

2.2、Set遍历

1、Iterate()迭代器方式(collection 集合共有方法)

for(Iterator<String>    it    =    list.iterator();    it.hasNext();    )    {   
       ....   
   }   
   这种方式在循环执行过程中会进行数据锁定, 性能稍差。如果想在遍历中去掉某个元素,只能调用it.remove方法,不能使用list.remove方法,否则一定出现并发访问的错误。

2、增强for

for(String   data    :    list)    {   
       .....   
   }   
   内部调用第一种,比Iterator 慢,这种循环方式还有其他限制, 不建议使用它。

 public void traversingSet(Set<String> set){
        //方法一:Iterator迭代器遍历
        Iterator<String> itr = set.iterator();
        while(itr.hasNext()){
            String str = itr.next();
            System.out.println(str);
        }
        
      //方法二:通过增强型for循环遍历
      //注:Set集合中不存在下标,因此无法通过下标遍历,对于Java编译器而言,方法一和方法二是等价的
        for (String str : set) {
            System.out.println(str);
        }
    }

2.3、Map遍历

  • ntrySet() 遍历
  • keySet()遍历
Map<Integer, String> map = new HashMap<>();
        map.put(1,"a");
        map.put(2,"b");
        map.put(3,"c");
        //1、entrySet()转set遍历
        Set<Map.Entry<Integer, String>> entry = map.entrySet();
        Iterator iterator = entry.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next());//1=a2=b3=c
        }
        //2、entrySet遍历
        for (Map.Entry<Integer, String> entrySet: map.entrySet()) {
            System.out.print(entrySet.getKey() + ":" + entrySet.getValue());//1:a2:b3:c
        }
        //3、keySet
        Set<Integer> keySet = map.keySet();
        for (Integer key:keySet) {
            System.out.print(key + ":" + map.get(key));1:a2:b3:c
        }

        //4、keySet()转set()
        for (Iterator i = map.keySet().iterator(); i.hasNext();) {
            Object obj = i.next();
            System.out.print(obj + ":" + map.get(obj));1:a2:b3:c
        }

2.4、数组遍历

Arrays.toString(s))

相关文章