一、集合类

集合的由来:

面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就需要将对象进行存储,集合就是存储对象最常用的一种方式。

集合特点:
1,用于存储对象的容器。(容器本身就是一个对象,存在于堆内存中,里面存的是对象的地址)
2,集合的长度是可变的。
3,集合中不可以存储基本数据类型值。 (只能存对象)

小问题:想存基本数据类型怎么办?  装箱、拆箱。例:al.add(5);可以这样写   // 相当于al.add(new Integer(5));

集合和数组的区别:

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

集合框架的构成及分类:(虚线为接口)


二、 Collection接口

Collection子接口以及常用实现类:

Collection接口
  |--List接口:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

    |--Vector:内部是 组 数据结构,是同步的。增删,查询都很慢!100%延长(几乎不用了)  
    |--ArrayList:内部是 数组 数据结构,是不同步的。替代了Vector,查询的速度快,增删速度慢。50%延长。(查询时是从容器的第一个元素往后找,由于数组的内存空间是连续的,所以查询快;增删的话所有元素内存地址都要改变,所以增删慢。
    |--LinkedList:内部是 链表 数据结构,是不同步的。增删元素的速度很快。(同理,链表的内存空间是不连续的,所以查询慢;增删时只需改变单个指针的指向,所以快;

  |--Set接口:无序,元素不能重复。Set接口中的方法和Collection一致。

    |--HashSet: 内部数据结构是哈希表 ,是不同步的。

  

List接口:

有一个最大的共性特点就是都可以操作角标,所以LinkedList也是有索引的。list集合可以完成对元素的增删改查。

Set和List的区别:

1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。

2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>

3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

ArryList和Vector可变长度数组的原理:

当默认长度的数组不够存储时,会建立一个新数组。将原来数组的内容拷贝到新的数组当中,并将新增加的元素追加到拷贝完的数组尾,如果仍然不够重复上述动作。其中,ArryList的增加是以原来50%长度进行增加,而Vector是按照100%延长。

ArryList是线程不安全的,Vector是安全的:

由于是否有锁的判断将影响效率,故Arrylist效率远远高于Vector。而且只要是常用的容器就不是同步的,因为同步效率比较低。

ArryList存取对象的一个小例子:

        Person p1 = new Person("lisi1",21);

        ArrayList al = new ArrayList();
        al.add(p1);
        al.add(new Person("lisi2",22));
        al.add(new Person("lisi3",23));
        al.add(new Person("lisi4",24));

        Iterator it = al.iterator();
        while(it.hasNext()){
//          System.out.println(((Person) it.next()).getName()+"::"+((Person) it.next()).getAge());
            //错误方式:不能这样取,next()一次指针会移动一次,会输出“lisi1::22 lisi3::24”
            // 正确方式:拿到一个Person对象,然后取属性。
            Person p = (Person) it.next();
            System.out.println(p.getName()+"--"+p.getAge());
        }  

三、Iterator接口

对 collection 进行迭代的迭代器,即对所有的Collection容器进行元素取出的公共接口。

该迭代器对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在具体容器中进行内部实现的。(内部类,可以看具体容器的源码)

对于使用容器者而言,具体的实现方法不重要,只要通过具体容器获取到该实现的迭代器的对象即可,也就是iterator方法,而不用new。(Iterator<String> ite=list.iterator();)

小知识点:使用迭代器过程中while和for的区别

 第一种
 Iterator<String> ite=list.iterator();
      while(ite.hasNext())//判断下一个元素之后有值
      {
          System.out.println(ite.next());
      }
 第二种
 Iterator<String> ite=list.iterator();
 for(Iterator it = coll.iterator(); it.hasNext(); ){
             System.out.println(it.next());
         }

第一种方法while循环结束后迭代器对象还在内存中存在,还能继续使用迭代器对象。

第二种方法for循环结束后迭代器对象就消失了,清理了内存,开发中第二种常用。

Iterator的一个子接口

  |--ListIterator接口(列表迭代器)

适用情况例子:(出现ConcurrentModificationException异常时)

出现异常情况代码:

Iterator it = list.iterator();
        while(it.hasNext()){

            Object obj = it.next();//java.util.ConcurrentModificationException
                            //在使用迭代器的过程中使用集合操作元素,容易出现异常。
                        //可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。 

            if(obj.equals("abc2")){
                list.add("abc9");
            }
            else
                System.out.println("next:"+obj);
        }
        System.out.println(list);  

解决办法代码:

public static void main(String[] args) {

        List list = new ArrayList();
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");

        System.out.println("list:"+list);
        ListIterator it = list.listIterator();//获取列表迭代器对象
        //它可以实现在迭代过程中完成对元素的增删改查。
        //注意:只有list集合具备该迭代功能.

        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("abc2")){
                it.add("abc9"); //ListIterator提供了add方法
            }
        }

HashSet之覆盖hashCode方法和equals方法 

如何保证HashSet的元素唯一性呢?
是通过对象的hashCode和equals方法来完成对象唯一性的:
->如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
->如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true:
  如果为true,视为相同元素,不存;如果为false,那么视为不同元素,就进行存储。

记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法,以建立对象判断是否相同的依据。

例:往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。

import java.util.HashSet;
import java.util.Iterator;

class Person {

	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public int hashCode() {
		// System.out.println(this+".......hashCode");
		return name.hashCode() + age * 27; // 乘以一个任意数,防止加了年龄以后HashCode仍相同
	}

	@Override
	public boolean equals(Object obj) {
		// 健壮性判断
		if (this == obj)
			return true;
		if (!(obj instanceof Person))
			throw new ClassCastException("类型错误");
		// System.out.println(this+"....equals....."+obj);

		Person p = (Person) obj;
		return this.name.equals(p.name) && this.age == p.age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String toString() {
		return name + ":" + age;
	}
}

public class HashSetTest {

	public static void main(String[] args) {
		HashSet hs = new HashSet();
		/*
		 * HashSet集合数据结构是哈希表,所以存储元素的时候,
		 * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。
		 *
		 */
		hs.add(new Person("lisi4", 24));
		hs.add(new Person("lisi7", 27));
		hs.add(new Person("lisi1", 21));
		hs.add(new Person("lisi9", 29));
		hs.add(new Person("lisi7", 27));

		Iterator it = hs.iterator();
		while (it.hasNext()) {
			Person p = (Person) it.next();
			System.out.println(p);
		}
	}
}

  

运行结果:

lisi1:21
lisi9:29
lisi4:24
lisi7:27

四、Map接口

Map:一次添加一对元素。Collection 一次添加一个元素。
  Map也称为双列集合,Collection集合称为单列集合。
  其实map集合中存储的就是键值对。
  map集合中必须保证键的唯一性。

常用方法:
1,添加。
value put(key,value):返回前一个和key关联的值,如果没有返回null.

2,删除。
void clear():清空map集合。
value remove(key):根据指定的key翻出这个键值对。

3,判断。
boolean containsKey(key):是否包含该key
boolean containsValue(value):是否包含该value
boolean isEmpty();是否为空

4,获取。
value get(key):通过键获取值,如果没有该键返回null。当然,可以通过返回null,来判断是否包含指定键。
int size(): 获取键值对的个数。

Map常用的子类:
  |--Hashtable :内部结构是哈希表,是同步的。不允许null作为键,null作为值。
  |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
  |--HashMap : 内部结构是哈希表,不是同步的。允许null作为键,null作为值。
  |--TreeMap : 内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

Map的迭代方法:

  Map本身没有迭代器。

  方法一:利用Map接口的values()方法,返回此映射中包含的值的 Collection (值不唯一),

      然后通过Collecion的迭代器进行迭代。(只需要Value,不需要Key的时候)

public class MapDemo {

	public static void main(String[] args) {

		Map<Integer,String> map = new HashMap<Integer,String>();
		method_2(map);
	}

	public static void method_2(Map<Integer,String> map){

		map.put(8,"zhaoliu");
		map.put(2,"zhaoliu");
		map.put(7,"xiaoqiang");
		map.put(6,"wangcai");

		Collection<String> values = map.values();

		Iterator<String> it2 = values.iterator();
		while(it2.hasNext()){
			System.out.println(it2.next());
		}
        }
} 

  方法二:通过keySet方法获取map中所有的键所在的Set集合(Key和Set的都具有唯一性),

      再通过Set的迭代器获取到每一个键,再对每一个键通过Map集合的get方法获取其对应的值即可。(比较好用)

		Set<Integer> keySet = map.keySet();
		Iterator<Integer> it = keySet.iterator();

		while(it.hasNext()){
			Integer key = it.next();
			String value = map.get(key);
			System.out.println(key+":"+value);
		}

  方法三:利用Map的内部接口Map.Entry<K,V>。

      通过Map的entrySet()方法,将键和值的映射关系作为对象存储到Set集合中

      这个映射关系的类型就是Map.Entry类型(结婚证)。

      再通过Map.Entry对象的getKey和getValue获取其中的键和值。

		Set<Map.Entry<Integer, String>> entrySet = map.entrySet();

		Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();

		while(it.hasNext()){
			Map.Entry<Integer, String> me = it.next();
			Integer key = me.getKey();
			String value = me.getValue();
			System.out.println(key+":"+value);
		}

  

Java集合框架,未完的更多相关文章

  1. (未完)Java集合框架梳理(基于JDK1.8)

    Java集合类主要由两个接口Collection和Map派生出来的,Collection派生出了三个子接口:List.Set.Queue(Java5新增的队列),因此Java集合大致也可分成List. ...

  2. 【java集合框架源码剖析系列】java源码剖析之TreeMap

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于TreeMap的知识. 一TreeMap的定义: public class TreeMap&l ...

  3. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  4. 【JAVA集合框架之Map】

    一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...

  5. Java集合框架之Collection接口

    Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...

  6. Java集合框架中Map接口的使用

    在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不 ...

  7. java集合框架之java HashMap代码解析

     java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...

  8. Java集合框架的知识总结(1)

    说明:先从整体介绍了Java集合框架包含的接口和类,然后总结了集合框架中的一些基本知识和关键点,并结合实例进行简单分析. 1.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象 ...

  9. Java集合框架的知识总结

    说明:面试准备,写的挺不错的. 转载地址: http://www.cnblogs.com/zhxxcq/archive/2012/03/11/2389611.html 1.综述 所有集合类都位于jav ...

  10. 浅入深出之Java集合框架(中)

    Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

随机推荐

  1. 五个数据段之代码段、数据段、BSS、栈、堆

    继上文讲完了对内存管理的一些知识,下面笔者再对上篇文章的内容加以拓展,那么我们今天就来说一说5个数据段 五个数据段 进程(执行的程序)会占用一定数量的内存,它或是用来存放磁盘载入的程序代码,或是存放取 ...

  2. 福州大学软工 1715 | K 班 - 启航

    福州大学软工 1715 | K 班 - 启航 愉快的暑假已经接近尾声了,我猜很多同学的暑假都过得轻松,毕竟是夏天(空调/WiFi/西瓜).不过呢,暑假期间的老师.助教们可没有闲着,都在为接下来的软工实 ...

  3. Swing-JTable检测单元格数据变更事件

    在JTable的初级教程中往往会提到,使用TableModel的 addTableModelListener方法可以监听单元格数据的变更,在其事件处理函,数tableChanged中,可以通过e.ge ...

  4. 201521123101 《Java程序设计》第8周学习总结

    1. 本周学习总结 2. 书面作业,本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 学习使用泛型,熟悉定义泛型,熟悉List中实现删除 2.统计文字中的单词数量并按出现 ...

  5. 201521123005 《java程序设计》 第六周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  6. Java课程设计—学生成绩管理系统(201521123005 杨雪莹)

    一.团队课程设计博客链接 学生成绩管理系统 二.个人负责模块或任务说明 学生成绩录入 显示所有学生信息 显示各科平均成绩 显示学生成绩(按降序排序) 三.自己的代码提交记录截图 四.自己负责模块或任务 ...

  7. 201521123095 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1. ...

  8. 201521123003《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  9. 万物皆对象的JavaScript

    写在前面: 经过前段时间对于H5语言的学习,开始慢慢适应现在的生活节奏和代码语言.从一开始的毫无头绪到现在可以大概地写出部分的网站静态页面,用了两个周的时间.作为一个之前从未接触过计算机语言的初学者来 ...

  10. 全局光照:光线追踪、路径追踪与GI技术进化编年史

    全局光照(Global Illumination,简称 GI), 作为图形学中比较酷的概念之一,是指既考虑场景中来自光源的直接光照,又考虑经过场景中其他物体反射后的间接光照的一种渲染技术. 大家常听到 ...