集合(Collection)

1. 什么是集合?

集合是一组对象组成的一个整体,又称为容器,集合类属于java.util包。集合不同于数组的地方在于,一是它的容量是可变的,二是集合中只能存储对象,不能存储基本数据类型

Java的集合类库有一大一小两派,一大由Collection接口带领,一小由Map接口带领。

2. Collection接口

Collection接口下有两大分支,分别为List接口和Set接口。注意,Collection是接口,而Collections则是java.util包下的一个具体类。

2.1 List接口

List集合中允许有重复对象。

2.1.1 ArrayList类

ArrayList分配了一个动态再分配的对象数组数组(说白了就是长度可变的数组),可以通过索引进行随机访问,但是插入删除比较麻烦,这与数组的特性是一致的。

List list = new ArrayList();

注:ArrayList是线程不安全的,即它的方法没有同步;而Vector是线程安全的,它的所有方法都是同步的。

2.1.2 LinkedList类

LinkedList采用链表结构保存对象,插入删除方便,但是访问慢,这和链表的特性是一致的。

List list2 = new LinkedList();

 import java.util.ArrayList;
 import java.util.List;

 public class Gather{
     public static void main(String[] args) {
         List list = new ArrayList<>();
         for(char ch = 'a'; ch <= 'z'; ch++){
             list.add(ch);
         }

         int ran = (int)(Math.random()*(list.size()-1));
         System.out.println("随机获取list中的元素:"+list.get(ran));

         list.remove(2);
         for(int i = 0; i < list.size(); i++){
             System.out.print(list.get(i)+" ");
         }
     }
 }

ArrayList示例

2.2 Set接口

Set是没有重复元素的集合,遍历Set集合的顺序和插入顺序并不总是一致,Set集合中的元素可以看作是无序的。

2.2.1 HashSet类

HashSet基于散列表

举例:

 public class People {
     private String name;
     private long id_card;
     public People(String name, long id_card){
         this.name = name;
         this.id_card = id_card;
     }

     public long getId_card(){
         return id_card;
     }

     public void setId_card(long id_card){
         this.id_card = id_card;
     }

     public String getName(){
         return name;
     }

     public void setName(String name){
         this.name = name;
     }
 }
 ——————————华丽的分割线————————————
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;

 public class CollectionDemo {

     public static void main(String[] args) {
         Set<People> hashSet = new HashSet<People >();
         hashSet.add(new People("张三", 2000));
         hashSet.add(new People("李四", 2001));
         hashSet.add(new People("王五", 2002));

         Iterator<People> it = hashSet.iterator();
         System.out.println("集合中的元素是:");
         while(it.hasNext()){
             People person = it.next();
             System.out.println(person.getName()+" "+person.getId_card());
         }
     }
 }

HashSet示例

2.2.2 TreeSet类

TreeSet树集是一个有序集合,可以以任意顺序将元素插入到集合中。遍历时,按照排序后的顺序呈现,排序是用红黑树完成的。

TreeSet如何知道元素的大小呢,在默认情况下,TreeSet假定插入的元素实现了Comparable接口。这个接口定义了一个方法:

Public interface Comparable<T>{

Int compareTo(T other);

}

通过Comparable接口定义排列顺序有局限性。对于一个给定的类,只能实现这个接口一次,如果想要使用不同规则,多次对类对象进行排序,就要用到Comparator对象传递给TreeSet构造器来定义排序规则。Comparator接口声明了一个带有两个显式参数的compare方法:

Public interface Comparator<T>{

Int compare(T a, T b);

}

与compareTo方法一样,如果a位于b之前compare方法则返回负值,相等返回0,否则返回正值。

如果按照描述信息进行排序,就直接定义一个实现Comparator接口的类:

Class ItemComparator implements Comparator<Item>{

Public int compare(Item a, Item b){

String descrA = a.getDescription();

String descrB = b.getDescription();

Return descrA.compareTo(descrB);

}

}

然后将这个类的对象传递给树集的构造器:

ItemComparator comp = new ItemComparator();

SortedSet<Item> sortByDescrition = new TreeSet<>(comp);

(总是就是,在构造TreeSet时,传给它一个对象参数,这个对象是实现了Comparator接口的类的一个实例,它定义了一种比较TreeSet集中元素的规则,就酱紫(⊙o⊙)哦)

注:在Java中,散列表用链表数组实现,每个链表被称为桶(bucket)。要想查找表中对象的位置,就要先计算它的散列码(也就是哈希码hashCode),然后与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。例如,散列码76268,并且有128个桶,则对象应该保存在第108号桶中。

桶数是指用于收集具有相同散列值的桶的数目。标准类库使用的桶数是2的幂,默认值为16(为表大小提供的任何值都将被自动转换为2的下一个幂)。

散列表可以用于实现几个重要的数据结构,其中最简单的就是set类型。Set的add方法首先在集中查找要添加的对象,如果不存在,就将这个对象添加进去。

3.Map接口

Map提供了将键值映射到值的对象,键不能重复,一个键映射到一个值。

3.1 HashMap类

HashMap也叫散列映射表,它对键进行散列,散列或比较函数只能作用于键,与键关联的值不能进行散列或比较。

HashMap是基于哈希表的Map接口的实现,增删的效率更高。允许null值和null键。

3.2 TreeMap类

TreeMap也叫树映射表,用键的整体顺序对元素进行排序。

TreeMap类不仅实现了Map类,还实现了java.util.SortedMap接口,因此集合中元素具有一定的顺序。增删效率比HashMap差。由于映射关系是根据键对象按照一定的顺序排列的,所以不允许键值为null

 public class Emp {
     private String e_id;
     private String e_name;
     public Emp(String e_id,String e_name){
         this.e_id = e_id;
         this.e_name = e_name;
     }
     public String getE_id() {
         return e_id;
     }
     public void setE_id(String e_id) {
         this.e_id = e_id;
     }
     public String getE_name() {
         return e_name;
     }
     public void setE_name(String e_name) {
         this.e_name = e_name;
     }
 }
 —————————华丽的分割线———————————
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;

 public class MapText {
     public static void main(String[] args) {
         Map map = new HashMap();
         Emp emp = new Emp("001","zhangsan");
         Emp emp2 = new Emp("015","lisi");
         Emp emp3 = new Emp("009","wangyi");
         Emp emp4 = new Emp("011","tangbao");
         map.put(emp.getE_id(), emp.getE_name());
         map.put(emp2.getE_id(),emp2.getE_name());
         map.put(emp3.getE_id(), emp3.getE_name());
         map.put(emp4.getE_id(), emp4.getE_name());

         Set set = map.keySet();
         Iterator it = set.iterator();
         //HashMap的无序是指既不是按照添加顺序,也不是按照键值大小顺序
         /*HashMap中哈希码的定义
          *  public final int hashCode() {
             return Objects.hashCode(key) ^ Objects.hashCode(value);
             }
          *Objects类中哈希码的定义(Objects继承自Object)
          *public static int hashCode(Object o) {
             return o != null ? o.hashCode() : 0;
           }
          */
         System.out.println("HashMap类实现的Map集合,无序:");
         while(it.hasNext()){
             String str = (String)it.next();
             String name = (String)map.get(str);
             System.out.println(str+":"+name);
         }

         TreeMap treemap = new TreeMap();
         treemap.putAll(map);
         Iterator it2 = treemap.keySet().iterator();
         System.out.println("TreeMap 类实现的Map集合,键对象升序:");
         while(it2.hasNext()){
             String str = (String)it2.next();
             String name = (String)map.get(str);
             System.out.println(str+""+name);
         }
     }
 }

TreeMap和HashMap

3.3其它

  集合框架并没有将映射表视为一个集合,但是可以获得映射表的视图,这时一组实现了Collection接口的对象,或者它的子接口的视图。

  有3个视图,分别是:键集、值集合(不是集)和键/值对集。键与键/值对形成了一个集,这是因为在映射表中一个键只能有一个副本。

  Set<K> keySet()

  Collection<K> values()

  Set<Map.Entry<K,V>> entrySet()

  注意:keySet既不是HashSet,也不是TreeSet,而是实现了Set接口的某个其他类的对象。Set接口扩展了Collection接口。

4.Iterator接口

  通过迭代器Iterator接口可以遍历集合。

  Iterator接口位于java.util包下,它有3个方法:

  hasNext(): 如果还有元素可迭代,返回true

  next(): 返回迭代的下一个元素

  remove(): 删除上次调用next()方法时返回的元素(注意:对next()和remove()方法的调用具有相互依赖性,调用remove()之前没有调用next()是不合法的。如果想要删除后面的元素,必须通过调用next()越过前面的元素才行)

  反复调用next()方法可以遍历集合,但是当到达了集合末尾,会抛出NoSuchElementException。

 Collection<String> c = ...;
 Iterator<String> iter = c.iterator();
 while(iter.hasNext()){
     String element = iter.next();
     Do sth with element
 }
 //从Java SE 5.0 起,可以用for each循环来遍历
 for(String element : c){
     Do sth with element
 }

Iterator接口

4.1迭代顺序

  元素被访问的顺序取决于集合类型,如果对ArrayList进行迭代,从索引为0的位置开始,没迭代一次,索引加1。如果访问的是HashSet,元素将按随机顺序出现,虽然可以保证遍历,但无法预知访问次序。

4.2 ListIterator接口

 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.ListIterator;

 public class ListIteratorDemo {
     public static void main(String[] args) {
         ArrayList<Integer> array = new ArrayList<>();
         Collections.addAll(array, 1,2,3,4,5,6);
         System.out.println("集合中的元素:"+array);
         ListIterator<Integer> iterator = array.listIterator();

         boolean hasNext = iterator.hasNext();
         System.out.println("集合是否还有下一个元素:"+hasNext);

         boolean hasPrevious = iterator.hasPrevious();
         System.out.println("集合是否还有前一个元素:"+hasPrevious);
             System.out.println("nextIndex:"+iterator.nextIndex());
         System.out.println("next:"+iterator.next());
         System.out.println("nextIndex:"+iterator.nextIndex());
         System.out.println("next:"+iterator.next());
         System.out.println("previousIndex:"+iterator.previousIndex());
         System.out.println("previous:"+iterator.previous());

         System.out.println("nextIndex:"+iterator.nextIndex());
         System.out.println("next:"+iterator.next());

         //add将元素插入到nextIndex所指的位置
         System.out.println("nextIndex:"+iterator.nextIndex());
         iterator.add(999);
         System.out.println("向集合中添加999后:"+array);

         //set将next()返回的元素替换为100
         iterator.next();
         iterator.set(100);
         System.out.println("集合中的元素:"+array);

         //remove将100删除
         iterator.remove();
         System.out.println("集合中的元素:"+array);
     }
 }

ListIterator

5.Deque接口

  Java SE 6中引入了Deque接口,并由ArrayDeque和LinkedList类实现。这两个类都提供了双端队列。在必要时可增加队列长度。

  public interface Deque<E> extends Queue<E>

6.集合框架

  框架(framework)是一个类的集,它奠定了创建高级功能的基础。框架包含很多超类,这些超类拥有非常有用的功能、策略和机制。框架使用者创建的子类可以扩展超类的功能,而不必重新创建这些基本的机制。例如,Swing就是一种用户界面的机制。

Java学习日记-10 集合的更多相关文章

  1. Java学习日记-11 集合(1)

    Collection接口集合中存储的只是对象的引用,不是对象本身. 1.ArrayList<E>类1.1ArrayList和Collection的关系 public interface L ...

  2. Java学习日记-12 集合(2)

    一.List<E>接口(超级接口Collection,List比Collection多重载了一些索引作为形参的方法)1.实现类ArrayList\LinkedListArrayList顺序 ...

  3. Java学习笔记之---集合

    Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...

  4. Java学习笔记之集合

    集合(Collection)(掌握) (1)集合的由来? 我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组而数组的长度固定 ...

  5. 【原】Java学习笔记026 - 集合

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:从三国演义中 ...

  6. java学习笔记之集合家族2

    集合体系 一.数据结构 List集合储存数据结构 <1>堆栈结构 特点:先进后出 <2>队列结构 特点:先进先出 <3>数组结构 特点:查询快,增删慢 <4& ...

  7. Java 学习(10):java 异常处理

    java 异常处理 异常发生的原因有很多,通常包含以下几大类: 用户输入了非法数据. 要打开的文件不存在. 网络通信时连接中断,或者JVM内存溢出. 三种类型的异常: 检查性异常: 最具代表的检查性异 ...

  8. Java学习日记基础篇(九) —— 集合框架,泛型,异常

    集合框架 有事我们会需要一个能够动态的调整大小的数组,比如说要添加新员工但是数组已经满了,并且数组的大小是在定义的时候定死的,所以我们就需要一个能够动态调整大小的数组或者用链表解决,而java中提供了 ...

  9. Java学习日记 集合

    一.接口Map<K,V>1.V put(K key, V value)2.int size()3.public class HashMap<K, V> implements M ...

随机推荐

  1. Html----常见标签

    文本格式化标签 标签 描述 <b> 定义粗体文本. <big> 定义大号字. <em> 定义着重文字. <i> 定义斜体字. <small> ...

  2. jquery获取value值

    $(function(){ alert(1); var a=$("#a004").val(); var a1=$("#b004").val(); //.val就 ...

  3. sql查阅每一月的数据

    因为项目中需要做数据报表的功能,需要统计每个月的销售额.我找到下面的sql语句.后来经过自己的测试,发现第二句才是可以用的, //String sql="SELECT year(buydat ...

  4. datazen Active Directory AD 配置

    今天苦心经营的datazen 链接AD,文档已经无法吐槽了简单的几句话,根本不够用. 先说一下链接AD 的好处吧, 1 首先免去设置密码的麻烦,因为直接用AD账号的密码. 2 更安全,因为客户可不想自 ...

  5. 想加入一行代码吗?使用<code>标签

    在介绍语言技术的网站中,避免不了在网页中显示一些计算机专业的编程代码,当代码为一行代码时,你就可以使用<code>标签了,如下面例子: <code>var i=i+300;&l ...

  6. eclipse设置和优化

    1.eclipse下的编码设置: eclipse 中使用模板新建 JSP,xhtml等 文件时,默认的编码为:ISO-8859-1. ISO-8859-1 编码对于中文的显示是不支持的,如果要支持简体 ...

  7. spring resttemplate中的转码

    /* * 初始化RestTemplate,RestTemplate会默认添加HttpMessageConverter * 添加的StringHttpMessageConverter非UTF-8 所以先 ...

  8. 初涉JavaScript模式 (5) : 原型模式 【一】

    什么是原型模式? 原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象.--引自JavaScript设计模式 我们创建的每一个函数都有一个prototype ...

  9. 延迟加载并渐现内容的jquery插件lazyFade

    http://www.jqcool.net/demo/201412/jquery-lazyfade/

  10. centos 下搭建 php环境(2) mysql 安装

    CentOS下的MySQL 5.1安装   01 1.下载源码包 wget http://mysql.llarian.net/Downloads/MySQL-5.1/mysql-5.1.63.tar. ...