目录
1、直接打印集合对象
1.1、打印 list 对象
运行原理:
打印集合对象
原理:
1.2、打印Set对象
运行原理:
1.3、打印Map对象
运行原理:
1.4、数组对象
总结:
2、集合遍历方式
2.1、List遍历
1、Iterate()迭代器方式(collection 集合共有方法)
2、增强for
3、普通fori 方式遍历i
Java8中:
4、forEach()
5、stream().forEach()
6、parallelStream().forEach()
2.2、Set遍历
1、Iterate()迭代器方式(collection 集合共有方法)
2、增强for
2.3、Map遍历
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))