j2ee 标签如何遍历arraylist
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了j2ee 标签如何遍历arraylist相关的知识,希望对你有一定的参考价值。
<%
ArrayList al = (ArrayList)UserServices.findAllList();
for(int i=0;i<al.size();i++)
UserBean ub = (UserBean)al.get(i);
%>
请问要改用标签库如何实现呢,希望给出代码,不要给我资料了.....
$auser.name
</c:forEach>
items="$users"相当于将类中request.setAttribute("users", users);取过来
var="auser" 相当于将集合中的值一个个取出来赋给一个对象
$auser.name是获得auser对象的name值 参考技术A <c:foreach var="" items="" scope="">
//
</c:foreach>
我就告诉你这个了。你自己查查吧。这个是JSTL标准标签库。迭代标签 参考技术B 如果是struts2的话,在Action里,
ArrayList al = (ArrayList)UserServices.findAllList();
List<UserBean> al1 = new ArrayList<UserBean>();
for(int i=0;i<al.size();i++)
UserBean ub = (UserBean)al.get(i);
ali.add(ub);
request.setAttrbute("al",al1);
<s:iterator value="#request.al" id="al">
<s:property value="#al.num" />
<s:property value="#al.name" />
<s:property value="#al.sex" />
<s:property value="#al.age" />
</s:iterator> 参考技术C <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:forEach items="$al" var="ub" varStatus="index">
$ub.
</c:forEach> 参考技术D ArrayList遍历的4种方法
package com.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListDemo
public static void main(String args[])
List<String> list = new ArrayList<String>();
list.add("luojiahui");
list.add("luojiafeng");
//方法1
Iterator it1 = list.iterator();
while(it1.hasNext())
System.out.println(it1.next());
//方法2 怪异!
for(Iterator it2 = list.iterator();it2.hasNext();)
System.out.println(it2.next());
//方法3
for(String tmp:list)
System.out.println(tmp);
//方法4
for(int i = 0;i < list.size(); i ++)
System.out.println(list.get(i));
仅供参考。
常见ArrayLIst面试题
文章目录
ArrayList
1,甚至可以存放null
2.基于数组是实现数组存储
3.无线程安全控制,即线程不安全,基本等同于Vector ,在多线程情况下不建议ArrayList
数组扩容效率问题
当需要加入的数据量特别多,如果是无参的话,数组的容量是逐渐增加的,那么就会触发很多次的扩容,因为扩容的时候会使用到数组拷贝,这个过程很耗费性能,会导致ArrayList效率下降
//这里是测试当添加很多数据时,ArrayList性能急剧下降的问题
public class AddManyElementProblem
public static void main(String[] args)
add1();
// 如果指定了容量
public static void add1()
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("hello");
list.add("PHP");
list.add("Java");
long startTime = System.currentTimeMillis();
//需求:还需要添加10W条数据
for (int i = 0; i < 100000; i++)
// 优化效果图
// 注意:这种优化方式只针对特定的场景,如果添加的元素是少量的、未知的,不推荐使用
// 4.3 ArrayList插入或删除元素一定比LinkedList慢么?
// 根据索引删除
// 案例:ArrayList和LinkedList对比
list.add(i+"");
long endTime = System.currentTimeMillis();
System.out.println("未指定容量: "+ (endTime - startTime));
//创建集合的时候指定足够大的容量
List<String> list1 = new ArrayList<String>(100000);
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++)
list1.add(i+"");
endTime = System.currentTimeMillis();
System.out.println("指定容量: "+ (endTime - startTime));
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t1Kgj232-1658498591138)(images.images/image-20220722213420918.png)]
底层和源码分析
1.维护了一个Objec的数组,transient Object[] elementData
2 当创建对象时,若使用无参构造,则初始容量为0,此时第一次添加就需要扩容为10,如需再次扩容为1.5倍
3.如果使用指定大小构造器,扩容同样1.5
添加方法:
首先确定索引是否范围合理,然后确定容量是否满足,这里的原理是:在极端情况下,此时容量=长度=size,那么当前所需要的最小长度是size+1,假如size+1大于当前长度,就应该扩容。如果不需要扩容,那么直接赋值即可
public void add(int index, E element)
rangeCheckForAdd(index);//检测索引范围是否正确
ensureCapacityInternal(size + 1); //这里是判断是否需要扩容,原理是:在极端情况下,此时容量=长度=size,那么当前所需要的最小长度是size+1,假如size+1大于当前长度,就应该扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
modCount记录修改次数,minCapacity-elementData.length若大于零,代表当前长度不够存储
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEIIKpXh-1658498591138)(images.images/image-20220601104236172.png)]
private void grow(int minCapacity)
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//原先数组1.5倍,但是第一次是0
if (newCapacity - minCapacity < 0)//如果,
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//若大于最大数组限制
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 真正扩容的是这里,拷贝到新数组并且设置新的容量
elementData = Arrays.copyOf(elementData, newCapacity);
扩容
无参构造创建时容量为0,第一次add时候会扩容,否则他内部数组就是一个空数组,然后每次数组满之后,再次添加,会触发扩容机制,扩容1.5倍
有参构造,创建时容量为传入的值,数组满之后,再次添加,会触发扩容机制,扩容1.5倍。
注意:扩容的时机都是内部数组满了之后,再次add才会扩容
添加流程
ensureCapacityInternal:判断是否扩容
public boolean add(E e)
ensureCapacityInternal(size + 1); //这里判断是否要扩容,size+1代表着极端情况下最小的容量,因为极端情况下,当前数组满了,所有需要的最小容量是size+1
elementData[size++] = e;
return true;
private void ensureCapacityInternal(int minCapacity)
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
3.确定minCapacity,若使用的是无参构造,那么初始时容量为0,当第一次添加的时候,这里就会返回10。还有一种情况,就是有参构造,但是传值小于DEFAULT_CAPACITY,也会返回DEFAULT_CAPACITY,10。这样做的目的时防止当容量小时,添加元素会触发多次扩容。例如如果传入2,那么在添加了两个元素,就要扩容,然后此时2*1.5=3,添加第四个元素还需要扩容,会触发多次扩容,影响性能。
private static int calculateCapacity(Object[] elementData, int minCapacity)
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
return minCapacity;
4.确定修改次数,再查看当前所需要的minCapacity和数组长度的差,若需要扩容再扩容
private void ensureExplicitCapacity(int minCapacity)
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
private void grow(int minCapacity)
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//每次1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;//第一次调用这个方法,因为oldCapacity为0
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:若超越了最大的容量进入这里
//将前newCapacity个拷贝至elementData
elementData = Arrays.copyOf(elementData, newCapacity);
有参构造
public ArrayList(int initialCapacity)
if (initialCapacity > 0)
this.elementData = new Object[initialCapacity];
else if (initialCapacity == 0)
this.elementData = EMPTY_ELEMENTDATA;
else
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
如何复制某个ArrayList到另一个ArrayList中去?
使用clone()方法
使用ArrayList构造方法
使用addAll方法
线程安全问题
当然不是线程安全的,线程安全版本的数组容器是Vector。 Vector的实现很简单,就是把所有的⽅法统统加上synchronized就完事了。 你也可以不使⽤Vector,⽤Collections.synchronizedList把⼀个普通ArrayList包装成⼀个线程安全版本 的数组容器也可以,原理同Vector是⼀样的,就是给所有的⽅法套上⼀层synchronized。
ArrayList插入或删除元素一定比LinkedList慢么
结果:
在数据量大的情况下,因为ArrayList底层数组, LinkedList底层双向链表。ArrayList增删时,越靠前头部,增删效率越低,因为ArrayList增删的时候是需要拷贝数组的。而LinkedList当增删、查找效率都不是很高,特别是对象处于链表中部位置
所以当插入删除元素在中间/或者随机查找的时候,数据量大的情况下,ArrayList可能会比LinkedList快。
public void add(int index, E element)
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index;//把索引位置的元素后移一格
elementData[index] = element;
size++;
public E remove(int index)
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);// 这里拷贝数据,即把待删除元素后面的元素覆盖到删除元素的位置
elementData[--size] = null; // clear to let GC do its work
return oldValue;
ArrayList适合做队列吗
队列一般都是FIFO的,先进先出,如果用ArrayList,那么就需要在数组头部删除,尾部添加,反过来也行,但是都会有一个操作涉及数组拷贝,比较耗费性能
ArrayList的遍历和LinkedList遍历性能⽐较如何
论遍历ArrayList要⽐LinkedList快得多,ArrayList遍历最⼤的优势在于内存的连续性,CPU的内部缓存 结构会缓存连续的内存⽚段,可以⼤幅降低读取内存的性能开销
ArrayList常⽤的⽅法总结
- boolean add(E e)
将指定的元素添加到此列表的尾部。
- void add(int index, E element)
将指定的元素插⼊此列表中的指定位置
- boolean addAll(Collection c)
按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
- boolean addAll(int index, Collection c)
从指定的位置开始,将指定 collection 中的所有元素插⼊到此列表中。
- void clear()
移除此列表中的所有元素。
- Object clone()
返回此 ArrayList 实例的浅表副本。
- boolean contains(Object o)
如果此列表中包含指定的元素,则返回 true。
- void ensureCapacity(int minCapacity)
如有必要,增加此 ArrayList 实例的容量,以确保它⾄少能够容纳最⼩容量参数所指定的元素数。
- E get(int index)
返回此列表中指定位置上的元素。
- int indexOf(Object o)
返回此列表中⾸次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
- boolean isEmpty()
如果此列表中没有元素,则返回 true int lastIndexOf(Object o) 返回此列表中最后⼀次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
- E remove(int index)
移除此列表中指定位置上的元素。
- boolean remove(Object o)
移除此列表中⾸次出现的指定元素(如果存在)。
- protected void removeRange(int fromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
- E set(int index, E element)
⽤指定的元素替代此列表中指定位置上的元素。 int size() 返回此列表中的元素数。
- Object[] toArray()
按适当顺序(从第⼀个到最后⼀个元素)返回包含此列表中所有元素的数组。
- T[] toArray(T[] a)
按适当顺序(从第⼀个到最后⼀个元素)返回包含此列表中所有元素的数组;返回数组的运⾏时类型是 指定数组的运⾏时类型。
- void trimToSize()
将此 ArrayList 实例的容量调整为列表的当前⼤⼩。
以上是关于j2ee 标签如何遍历arraylist的主要内容,如果未能解决你的问题,请参考以下文章