首页 > 代码库 > Java 容器在实际web项目中应用
Java 容器在实际web项目中应用
前言:在java开发中我们离不开集合数组等,在java中有个专有名词:“容器” ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用法。可结合图片代码了解Java中的容器
备注 :这个地方 ,参考于朝向远方的博客Java容器详解 ,既然前人总结的这么好,我就直接拿来用,在这里更注重在实际开发中的例子,感谢那些总结的前辈们,辛苦了。
简单的数组例子
Thinking in Java 中并没有把数组归为Java的容器,实际上数组的确不是Java独有的c++ ,c都有数组。但是,在web开发时我还是把数组归类到容器中,因为他们说白了都是在做相同的事情
另外还有一个细节点就是:我翻遍了我开发过的项目,但是很惊讶的发现,这么多项目里直接用数组存储对象极为少见。想想也是,java是面向对象的,而数组对java总归是有点偏底层。
珍惜这来之不易的demo吧:
@Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType") private byte[] globals;
数组(array)是最常见的数据结构。数组是相同类型元素的有序集合,并有固定的大小(可容纳固定数目的元素)。数组可以根据下标(index)来随机存取(random access)元素。在内存中,数组通常是一段连续的存储单元。
Java支持数组这一数据结构。我们需要说明每个数组的类型和大小,java利用byte[] 可以表示blob字段,存放图片,xml,json等。String[]则可以用来存一些字符串,id, code等。
public Map<String, String> getDimValue() { if (this.dimValue != null) return dimValue; this.dimValue = http://www.mamicode.com/new HashMap<String, String>(); if (this.dim != null && this.dim.length() != 0) { String[] strDims = this.dim.split(",");//可以用截取的方式,得到String[] for (String s : strDims) { String[] dims = s.split("\\:"); this.dimValue.put(dims[0], dims[1]);//数组访问通过下标,但是注意 最多到array[array.length-1],越界直接抛出异常,和c++不一样 } } return this.dimValue; }
在说明类型时,在类型说明(String)后面增加一个[],来说明是一个数组。使用new创建容器时,需要说明数组的大小;或者是 直接 int a = {1,2,3} 这样直接用{}同时初始化。
数组可以通过遍历的形式转为其他容器类型,但是其他类型可以通过 toArray()快速转为数组(下文中会说到Arrays这个工具类可以把数组转为List)
第一个分支:Collection
在开发中,Collection最常用的就是两个类: Set和List。因为同属于一个Collection下,相互转化方便,调用的方法也类似。(collection Api)
Java中常用方法接口:
* boolean add(Object obj): 添加对象,集合发生变化则返回true * Iterator iterator():返回Iterator接口的对象 * int size() * boolean isEmpty() * boolean contains(Object obj) * void clear() * <T> T[] toArray(T[] a)
上述接口参照于:wishyouhappy的博客:java容器总结。
1:List集合
具体可以查看list中文文档,文档中清楚的描述到List<E>是一个实现了 Collection的接口,而我们可以直接用List 声明对象(接口可以直接声明一个对象)。容器的引用为List类型,但容器的实现为ArrayList类。这里是将接口与实现类分离。事实上,同一种抽象数据结构(ADT)都可以有多种实施方法(比如栈可以实施为数组和链表)。这样的分离允许我们更自由的选择ADT的实施方式(参考于Java容器详解)
java中较为常用的 ArrayList,LinkedList, 集合中的元素可以相等,是有顺序的
1 public class Test { 2 public static void main(String[] args) { 3 List<String> list = new ArrayList<String>(); 4 //添加单个元素 5 for(String s1:"hehe wo shi lao da".split(" ")){ 6 list.add(s1); 7 } 8 //添加多个元素 9 list.addAll(Arrays.asList("nan dao ni bu xin?".split(" ")));//Arrays是一个工具类,可以帮助我们少些遍历代码 10 System.out.println(list.toString());//list重写了toString方法,输出list中每一个元素 11 //修改位置为i的元素 12 for(int i = 0; i<list.size();i++){ 13 list.set(i, "u"); 14 } 15 System.out.println(list.toString()); 16 list.removeAll(Arrays.asList(new String[]{"u"}));//这个地方为了测试 我初始化了一个字符数组 new String[]{"u"} 17 System.out.println(list.toString()); 18 19 } 20 }
上边的代码只是为了说明 list的主要用途,实际上开发中可能用不到这么多,比较常用的也就
- add()方法加入新的元素
- get()方法可以获取容器中的元素,传递一个整数下标作为参数
- remove()方法可以删除容器中的元素,传递一个整数下标作为参数。(有另一个remove(),传递元素自身作为参数)
- size()方法用来返回容器中元素的总数。
- toString() 多用于调试代码是,查看list中的内容
- addAll() 添加一个相同类型的list
2:Set集合
集合(set)也是元素的集合。集合中不允许有等值的元素,集合的元素没有顺序:
我们用Set多数时候是利用它的特性,没有重复的元素,例如:
public class Test { public static void main(String[] args) { Set<Integer> s1 = new HashSet<Integer>(); s1.add(4); s1.add(5); s1.add(4); s1.remove(5); System.out.println(s1); System.out.println(s1.size()); } }
我们可以用它去过滤重复数据,Set 可以轻松的转为List,因为构造方法传参是Collection<? extends E> c
1 Set<String> set = new HashSet<String>(); 2 set.add("h"); 3 set.add("h"); 4 List<String> fromSets = new ArrayList<String>(set); 5 System.out.println(fromSets.toString()); 6 Set<String> s1 = new HashSet<String>(fromSets); 7 System.out.println(s1.toString());
这个地方,非常有意思的是,HashSet中竟然持有的是HashMap,利用HashMap存取数据,下面是HashSet的源码
public HashSet(Collection<? extends E> c) { map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
HashSet只有add方法,没有get方法(这和list稍微不同)。但是HashSet 实现了Iterator<E> iterator()。可以通过Iterator遍历,具体可以查看Set中文文档
3:collection中的Iterator
Iterator的官方文档,一般Set想要取元素只能通过迭代器,而list=也可以用迭代器(一般都是用get)
public class Test { public static void main(String[] args) { List<Integer> l1 = new ArrayList<Integer>(); l1.add(4); l1.add(5); l1.add(2); Iterator i = l1.iterator(); while(i.hasNext()) { System.out.println(i.next()); } } }
第二个分支:Map
在web项目中,Map是非常常用的,当然在很多时候,Map会被一些包装类给替代掉(这实际上是敏捷开发中提到用vo替换map).但是Map还是无法阻挡的容器一哥。
Java中常用的方法接口
* Object get(Object key) * Object put(Object key, Object value) * Set keySet() : returns the keys set Set<K> keySet() * Set entrySet(): returns mappings set Set<Map.Entry<K,V>> entrySet() * containsKey() * containsValue()
Map是键值对的集合。Map中的每个元素是一个键值对,即一个键(key)和它对应的对象值(value)。对于Map容器,我们可以通过键来找到对应的对象。
哈希表是Map常见的一种实现方式
public class Test { public static void main(String[] args) { Map<String, Integer> m1 = new HashMap<String, Integer>(); m1.put("Vamei", 12); m1.put("Jerry", 5); m1.put("Tom", 18); System.out.println(m1.get("Vamei")); } }
在Map中,我们使用put()方法来添加元素,用get()方法来获得元素。
Map还提供了下面的方法,来返回一个Collection:
- keySet() 将所有的键转换为Set
- values() 将所有的值转换为List
总结:
java中有一些工具类来帮助我们处理容器相关的内容。比如Arrays,java中的一些类都有用到这些工具类
比如: ArrayList源码中的clone方法
/** * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The * elements themselves are not copied.) * * @return a clone of this <tt>ArrayList</tt> instance */ public Object clone() { try { ArrayList<E> v = (ArrayList<E>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn‘t happen, since we are Cloneable throw new InternalError(); } }
ArrayList源码中的 toArray()方法
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
如果你对Arrays这个工具类有兴趣,可以看一下源码,它最终调用到了本地方法(折叠起来,是不希望给读者带来困惑)
1 public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { 2 T[] copy = ((Object)newType == (Object)Object[].class) 3 ? (T[]) new Object[newLength] 4 : (T[]) Array.newInstance(newType.getComponentType(), newLength); 5 System.arraycopy(original, 0, copy, 0, 6 Math.min(original.length, newLength)); 7 return copy; 8 }
再比如Collections
有兴趣的可以去看一下源码,我觉得非常有帮助
Java 容器在实际web项目中应用