前言:在java开发中我们离不开集合数组等,在java中有个专有名词:“容器” ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用法。可结合图片代码了解Java中的容器

备注 :这个地方 ,参考于朝向远方的博客Java容器详解,既然前人总结的这么好,我就直接拿来用,在这里更注重在实际开发中的例子,感谢那些总结的前辈们,辛苦了。

简单的数组例子

  Thinking in Java 中并没有把数组归为Java的容器,实际上数组的确不是Java独有的c++ ,c都有数组。但是,在web开发时我还是把数组归类到容器中,因为他们说白了都是在做相同的事情

另外还有一个细节点就是:我翻遍了我开发过的项目,但是很惊讶的发现,这么多项目里直接用数组存储对象极为少见。想想也是,java是面向对象的,而数组对java总归是有点偏底层。

珍惜这来之不易的demo吧:

  1. public Map<String, String> getDimValue() {
  2. if (this.dimValue != null)
  3. return dimValue;
  4. this.dimValue = new HashMap<String, String>();
  5. if (this.dim != null && this.dim.length() != 0) {
  6. String[] strDims = this.dim.split(",");//可以用截取的方式,得到String[]
  7. for (String s : strDims) {
  8. String[] dims = s.split("\\:");
  9. this.dimValue.put(dims[0], dims[1]);//数组访问通过下标,但是注意 最多到array[array.length-1],越界直接抛出异常,和c++不一样
  10. }
  11. }
  12. return this.dimValue;
  13. }

数组(array)是最常见的数据结构。数组是相同类型元素的有序集合,并有固定的大小(可容纳固定数目的元素)。数组可以根据下标(index)来随机存取(random access)元素。在内存中,数组通常是一段连续的存储单元。

Java支持数组这一数据结构。我们需要说明每个数组的类型和大小,java利用byte[] 可以表示blob字段,存放图片,xml,json等。String[]则可以用来存一些字符串,id, code等。

  1. //web项目中倒是常用 byte[]来存放blob字段等
  1. @Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType")
  2. private byte[] globals;

  在说明类型时,在类型说明(String)后面增加一个[],来说明是一个数组。使用new创建容器时,需要说明数组的大小;或者是 直接 int a = {1,2,3} 这样直接用{}同时初始化。  

数组可以通过遍历的形式转为其他容器类型,但是其他类型可以通过 toArray()快速转为数组(下文中会说到Arrays这个工具类可以把数组转为List)

第一个分支:Collection

    在开发中,Collection最常用的就是两个类: Set和List。因为同属于一个Collection下,相互转化方便,调用的方法也类似。(collection Api

 Java中常用方法接口:

  1. * boolean add(Object obj): 添加对象,集合发生变化则返回true
  2. * Iterator iterator():返回Iterator接口的对象
  3. * int size()
  4. * boolean isEmpty()
  5. * boolean contains(Object obj)
  6. * void clear()
  7. * <T> T[] toArray(T[] a)

上述接口参照于:wishyouhappy的博客:java容器总结

1:List集合

  具体可以查看list中文文档,文档中清楚的描述到List<E>是一个实现了 Collection的接口,而我们可以直接用List 声明对象(接口可以直接声明一个对象)。容器的引用为List类型,但容器的实现为ArrayList类。这里是将接口与实现类分离。事实上,同一种抽象数据结构(ADT)都可以有多种实施方法(比如栈可以实施为数组和链表)。这样的分离允许我们更自由的选择ADT的实施方式(参考于Java容器详解)

  java中较为常用的 ArrayList,LinkedList, 集合中的元素可以相等,是有顺序的

  1. 1 public class Test {
  2. 2 public static void main(String[] args) {
  3. 3 List<String> list = new ArrayList<String>();
  4. 4 //添加单个元素
  5. 5 for(String s1:"hehe wo shi lao da".split(" ")){
  6. 6 list.add(s1);
  7. 7 }
  8. 8 //添加多个元素
  9. 9 list.addAll(Arrays.asList("nan dao ni bu xin?".split(" ")));//Arrays是一个工具类,可以帮助我们少些遍历代码
  10. 10 System.out.println(list.toString());//list重写了toString方法,输出list中每一个元素
  11. 11 //修改位置为i的元素
  12. 12 for(int i = 0; i<list.size();i++){
  13. 13 list.set(i, "u");
  14. 14 }
  15. 15 System.out.println(list.toString());
  16. 16 list.removeAll(Arrays.asList(new String[]{"u"}));//这个地方为了测试 我初始化了一个字符数组 new String[]{"u"}
  17. 17 System.out.println(list.toString());18
  18. 19 }
  19. 20 }

上边的代码只是为了说明 list的主要用途,实际上开发中可能用不到这么多,比较常用的也就

  • add()方法加入新的元素
  • get()方法可以获取容器中的元素,传递一个整数下标作为参数
  • remove()方法可以删除容器中的元素,传递一个整数下标作为参数。(有另一个remove(),传递元素自身作为参数)
  • size()方法用来返回容器中元素的总数。
  • toString() 多用于调试代码是,查看list中的内容
  • addAll() 添加一个相同类型的list

List中 还有一个实习类 LinkedList 比较常用,它可以用来做队列 的实现,也可以变相完成栈的工作。

主要方法有:

  •   get(int index):返回此列表中指定位置处的元素。
  • getFirst():返回此列表的第一个元素。
  • getLast():返回此列表的最后一个元素。
  • indexOf(Object o):返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
  • lastIndexOf(Object o):返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
  •  remove():获取并移除此列表的头(第一个元素)
  •  removeFirst():移除并返回此列表的第一个元素
  •  removeLast():移除并返回此列表的最后一个元素

ListedList采用的是链式存储。链式存储就会定一个节点Node。包括三部分前驱节点、后继节点以及data值。所以存储存储的时候他的物理地址不一定是连续的

具体内容可参照java提高篇(二二)---LinkedList   下面列出了linkedList的部分源码(不建议一开始就看)

2:Set集合

集合(set)也是元素的集合。集合中不允许有等值的元素,集合的元素没有顺序:

我们用Set多数时候是利用它的特性,没有重复的元素,例如:

2.1 HashSet:HashSet查询速度比较快,但是存储的元素是随机的并没有排序

  1. public class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5. Set<Integer> s1 = new HashSet<Integer>();
  6. s1.add(4);
  7. s1.add(5);
  8. s1.add(4);
  9. s1.remove(5);
  10. System.out.println(s1);
  11. System.out.println(s1.size());
  12. }
  13. }

我们可以用它去过滤重复数据,Set 可以轻松的转为List,因为构造方法传入参数是Collection<? extends E> c

  1. 1 Set<String> set = new HashSet<String>();
  2. 2 set.add("h");
  3. 3 set.add("h");
  4. 4 List<String> fromSets = new ArrayList<String>(set);
  5. 5 System.out.println(fromSets.toString());
  6. 6 Set<String> s1 = new HashSet<String>(fromSets);
  7. 7 System.out.println(s1.toString());

这个地方,非常有意思的是,HashSet中竟然持有的是HashMap,利用HashMap存取数据

  1. public HashSet(Collection<? extends E> c) {
  2. map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
  3. addAll(c);
  4. }

HashSet只有add方法,没有get方法(这和list稍微不同)。但是HashSet 实现了Iterator<Eiterator()。可以通过Iterator遍历,具体可以查看Set中文文档

2.2:TreeSet

TreeSet是将元素存储红-黑树结构中,所以存储的结果是有顺序的

  1. public static void main(String[] args){
  2. Random random=new Random(47);
  3. Set<Integer> intset=new TreeSet<Integer>();
  4. for (int i=0;i<10000;i++){
  5. intset.add(random.nextInt(30));
  6. }
  7. System.out.print(intset);
  8. }

3:collection中的Iterator

Iterator的官方文档,一般Set想要取元素只能通过迭代器,而list也可以用迭代器(一般都是用get)

  1. public class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5. List<Integer> l1 = new ArrayList<Integer>();
  6. l1.add(4);
  7. l1.add(5);
  8. l1.add(2);
  9. Iterator i = l1.iterator();
  10. while(i.hasNext()) {
  11. System.out.println(i.next());
  12. }
  13. }
  14. }

Collection可以用foreach,因为其实现了Iterator接口

  1. public class IteratorClass {
  2. public Iterator<String> iterator(){
  3. return new Itr();
  4. }
  5. private class Itr implements Iterator<String>{
  6. protected String[] words=("Hello Java").split(" ");
  7. private int index=0;
  8. public boolean hasNext() {
  9. return index<words.length;
  10. }
  11. public String next() {
  12. return words[index++];
  13. }
  14. public void remove() {
  15. }
  16. }
  17. }

foreach循环最终也会转化为Iterator遍历 (Iterator it=iterator;iterators.hasNext();)

  1. Iterator iterators=new IteratorClass().iterator();
  2. for (Iterator it=iterator;iterators.hasNext();) {
  3. System.out.println(iterators.next());
  4. }
  5. while (iterators.hasNext()){
  6. System.out.println(iterators.next());
  7. }

下面说一下Java中极容易出错的点:

  for 循环查找集合中某个元素并删除:极容易出现java.util.ConcurrentModificationException

  1. List<String> list = new ArrayList<String>();
  2. list.addAll(Arrays.asList("nan dao ni bu xin?".split(" ")));
  3. for(String st:list){
  4. System.out.println(st);
  5. if(st.equals("ni")){
  6. list.remove(st);
  7. }
  8. }

解决方式是将数组转化为Iterator,然后利用it.remove();删除数组中的元素

  1. public static void main(String[] args) {
  2. List<String> list=new ArrayList<String>();
  3. list.add("a");
  4. list.add("bb");
  5. list.add("a22");
  6. Iterator<String> it=list.iterator();
  7. //去除数组中"a"的元素
  8. while(it.hasNext()){
  9. String st=it.next();
  10. if(st.equals("a")){
  11. it.remove();
  12. }
  13. }
  14. }

第二个分支:Map

    在web项目中,Map是非常常用的,当然在很多时候,Map会被一些包装类给替代掉(这实际上是敏捷开发中提到用vo替换map).但是Map还是无法阻挡的容器一哥。

Java中常用的方法接口

  1. * Object getObject key
  2. * Object putObject key, Object value
  3. * Set keySet() : returns the keys set Set<K> keySet()
  4. * Set entrySet(): returns mappings set Set<Map.Entry<K,V>> entrySet()
  5. * containsKey()
  6. * containsValue()

   Map是键值对的集合。Map中的每个元素是一个键值对,即一个键(key)和它对应的对象值(value)。对于Map容器,我们可以通过键来找到对应的对象。

哈希表是Map常见的一种实现方式,也是实际开发中用的最广泛的 (HashMap),想要具体了解HashMap的原理,可以参考 hashmap实现原理浅析

  1. public class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5. Map<String, Integer> m1 = new HashMap<String, Integer>();
  6. m1.put("Vamei", 12);
  7. m1.put("Jerry", 5);
  8. m1.put("Tom", 18);
  9. System.out.println(m1.get("Vamei"));
  10. }
  11. }

在Map中,我们使用put()方法来添加元素,用get()方法来获得元素。

Map还提供了下面的方法,来返回一个Collection:

  • keySet()  将所有的键转换为Set
  • values()  将所有的值转换为List
  • containsKey验证主要是否存在、containsValue验证值是否存在
  • entrySet获取键值对。

总结:

    java中有一些工具类来帮助我们处理容器相关的内容。比如Arrays,java中的一些类都有用到这些工具类

ArrayList源码中的clone方法

  1. /**
  2. * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
  3. * elements themselves are not copied.)
  4. *
  5. * @return a clone of this <tt>ArrayList</tt> instance
  6. */
  7. public Object clone() {
  8. try {
  9. ArrayList<E> v = (ArrayList<E>) super.clone();
  10. v.elementData = Arrays.copyOf(elementData, size);
  11. v.modCount = 0;
  12. return v;
  13. } catch (CloneNotSupportedException e) {
  14. // this shouldn't happen, since we are Cloneable
  15. throw new InternalError();
  16. }
  17. }

ArrayList源码中的 toArray()方法

  1. public Object[] toArray() {
  2. return Arrays.copyOf(elementData, size);
  3. }

如果你对Arrays这个工具类有兴趣,可以看一下源码,它最终调用到了本地方法(折叠起来,是不希望给读者带来困惑)

Arrays的一些其他方法:

  •  sort():  对传入的集合排序 (具体算法可以参考Java Arrays.sort源代码解析
  •  aslist(): 把数组转为List
  • binarySearch():二分查找数组
  • deepToString():把二维数组转为String
  •  fill():快速填充数组

再比如Collections:

  可以参考thinking in java之Collections工具类的使用

  max():取集合的最大元素

  subList():截取list

  addAll():添加集合

有兴趣的可以去看一下源码,我觉得非常有帮助

Java 容器在实际项目中的应用的更多相关文章

  1. Java 容器在实际项目开发中应用

    前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用 ...

  2. Atitit.java c#.net php项目中的view复用(jsp,aspx,php的复用)

    Atitit.java c#.net php项目中的view复用(jsp,aspx,php的复用) 1.1. Keyword1 1.2. 前言1 2. Java项目使用.Net的aspx页面view1 ...

  3. 【Java心得总结六】Java容器中——Collection

    在[Java心得总结五]Java容器上——容器初探这篇博文中,我对Java容器类库从一个整体的偏向于宏观的角度初步认识了Java容器类库.而在这篇博文中,我想着重对容器类库中的Collection容器 ...

  4. 对Java Web项目中路径的理解

    第一个:文件分隔符 坑比Window.window分隔符 用\;unix采用/.于是用File.separator来跨平台 请注意:这是文件路径.在File f = new File(“c:\\hah ...

  5. 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理

    原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保留下! 文章宗旨:Talk is cheap show me the code. 大成若缺,其 ...

  6. java web项目中打开资源文件中文乱码

    1 java web项目中经常使用多模块管理.在某一个模块中添加了一些资源文件.但不是启动项目.有时候需要在程序中读取资源文件内容,打包后放到容器中就不能正常运行了.需要将所有资源文件放到启动项目的 ...

  7. java web项目(spring项目)中集成webservice ,实现对外开放接口

    什么是WebService?webService小示例 点此了解 下面进入正题: Javaweb项目(spring项目)中集成webservice ,实现对外开放接口步骤: 准备: 采用与spring ...

  8. Spring学习(四)在Web项目中实例化IOC容器

    1.前言 前面我们讲到Spring在普通JAVA项目中的一些使用.本文将介绍在普通的Web项目中如何实例化Spring IOC容器.按照一般的思路.如果在Web中实例化Ioc容器.这不得获取Conte ...

  9. 解构华为云HE2E项目中的容器技术应用

    摘要:本文从容器技术应用的角度解构了HE2E项目的代码仓库配置.镜像构建.及docker-compose的部署方式.希望通过本篇文章分享可以使更多的开发者了解容器技术和华为云. 本文分享自华为云社区& ...

随机推荐

  1. struts2.1.6教程十、类型转换

    建立struts2conversion项目,并搭建好struts2的基本开发环境 1.基于Action的直接属性转换 建立t.jsp页面,内容如下: <s:form action="p ...

  2. 2.solr学习速成之安装

    1.下载解压solr-5.3.1.tgz [root@205 opt]# tar -zxf solr-5.3.1.tgz -C /opt/module/ 2.将solr-5.3.1/server/so ...

  3. Smart.coder每日站立会议08

    站立会议内容: 完善小程序的查找功能,打算考虑一下信息自动输入分类的功能. 1.站立会议照片: 2.任务展板 3.燃尽图

  4. CoreML试水--图片识别

    今年的WWDC上,关于人工智能方面Apple开放了CoreML工具包. 今天就趁着时间还早果断的尝试了一下到底有多容易. import UIKit import CoreML import Visio ...

  5. [Leetcode] Binary tree level order traversal二叉树层次遍历

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...

  6. Android面试题目2

    1. 请描述下Activity的声明周期. onCreate->onStart->onRemuse->onPause->onStop->onRestart->onD ...

  7. QT调用百度语音REST API实现语音合成

    QT调用百度语音REST API实现语音合成 1.首先点击点击链接http://yuyin.baidu.com/docs/tts 点击access_token,获取access_token,里面有详细 ...

  8. Day1 - Python基础1 Python介绍、基本语法、流程控制习题集

    1.打印Hello World! print("Hello World!") 或 name="你好,世界!" print(name) 2.声明变量:打印name ...

  9. Swift 了解(1)

    Apple取消了oc的指针以及其他不安全的访问的使用,舍弃的smalltalk语法,全面改为点语法,提供了类似java的命名空间 范型 重载: 首先我们了解一下Swift这门语言.Swift就像C语言 ...

  10. Java基础——继承

    学习Java继承之前,我们想回忆一下Java面向对象需要特别注意的几个关键点. 面向对象是将复杂的事情简单化了,它通过封装的方式使得代码的重用性更高和安全性更强.平时我们要学会用面向对象的方式去思考, ...