Java集合功能与用法实例详解

本文实例讲述了Java集合功能与用法。分享给大家供大家参考,具体如下:

本文内容:

  • 什么是集合
  • Collection
  • Iterator
  • List
  • set
  • Map
  • Collections工具类

首发日期:2018-05-17


什么是集合:

  • 集合是一种新容器,集合可以存储数量不固定的元素(数组的空间是固定的,你申请多少空间以后都不能改变),而集合可以动态的增加空间(有些是空间不够时新建一个足够大的数组再把原来的元素移到新的数组中)。
  • 集合的出现解决的几个问题:
    • 存储数量不等的元素。
    • 定义了数据结构,所以集合的元素可以依据数据结构来读取,比如LinkList(可以理解成链表结构的数组),HashSet(哈希表结构)
    • 可以存储具有映射关系的元素(Map)
  • 集合中存储的元素都是对象(默认取出的也是一个Object对象),即使存入的是一个数字,也会转换成 Integer 类。
  • 集合存放的只是对象的引用
  • java中集合类体系主要分为两类:主要用于存储普通元素的Collection、用于存储具有映射关系的元素的Map

PS:

  • jdk1.5和jdk1.8新增的内容有点多,现在有点新特性没添上,以后有空再加上去吧。
  • Queue主要为了实现队列功能,这里不讲述,有兴趣自行查找。

Collection:

介绍:

  • collection是一个抽象接口,是List、Set和Queue接口的父接口

方法(父接口定义的方法,实现类中都会有)【具体使用看下面的具体实现类】:

  • 添加元素:

    • 添加一个元素X:add(X)
    • 添加集合X中全部元素到集合中:addAll(X)
  • 删除元素:
    • clear():移除此 collection 中的所有元素
    • remove(x):移除指定元素x
    • removeAll(x):移除集合中另一个集合x的元素
  • 检查:
    • size():检测集合的元素个数
    • isEmpty():检测集合是否为空,空返回true
    • contains(x):是否包含某元素x
    • containsAll(x):是否包含另一个集合x中的所有元素。
  • 其他:
    • toArray():将集合转成数组
    • iterator():返回可以在此集合上进行元素迭代的迭代器
    • equals(x):比较集合是否与x一致。

集合的获取依赖于迭代器Iterator。

补充:

  • 下面的各种具体实现类的构造方法都支持传入一个比较器,用于执行非自然排序(比如String的比较是字符,而我们可以定义成按字符长度排序。)【例子在TreeSet中。】

Iterator:

介绍:

  • Iterator是一个接口,它可以对Collection进行元素迭代(如果Collection返回了一个迭代器的话)
  • 基本每一个具体实现类中都实现了Iterator(内部实现),从而使得Iterator可以迭代所有的Collection的具体实现类的元素。

迭代方法:

  • hasNext():如果仍有元素可以迭代,则返回 true
  • next():迭代出下一个元素
  • remove():删除迭代器刚越过的元素(就是刚刚next到的元素)

示例:

package 集合;

import java.util.ArrayList;
import java.util.Iterator;
public class IteratorDemo {
  public static void main(String[] args) {
    ArrayList q=new ArrayList();
    //增
    q.add("a");
    q.add("b");
    q.add("c");
    q.add("d");
    //使用迭代器迭代
    for(Iterator it=q.iterator();it.hasNext();) {
      Object obj=it.next();
      System.out.println(obj);//a b c d
      if(obj=="a")
        it.remove();
    }
    //删除后查看一下
    System.out.println(q);
  }
}

补充:

  • 对于List,有一个特别的迭代器接口:ListIterator,这个迭代器专用于List,它比普通的接口多出了增加元素、修改元素、正反向迭代功能。
  • Iterator经常与foreach语句来搭配使用。
    • 但在1.5之后,Collection实现了Iterable接口,使得集合可以直接迭代了。

List:

介绍:

  • List是一个接口,定义的是存储的元素是有序的集合,
  • 实现List的集合可以使用下标来取出
  • 实现List的集合中元素可以是重复的。

特有方法(除了Collection中有的方法):

    • add(index,x):在集合的指定位置index插入指定元素x
    • addAll(index,x):从指定的位置开始,将集合x中的所有元素插入到此列表中。
    • remove(index):移除集合中指定位置index上的元素。
    • get(index):返回列表中指定位置的元素。 【因为List是有下标的,所以支持使用get来获取元素】
    • set(index, x)用指定元素x替换列表中指定位置index的元素 。
    • indexOf(X):返回集合中元素x的下标 。
    • subList(fromIndex,toIndex):根据下标,从集合中取出元素,返回的是一个List 。
    • listIterator():返回此列表中的元素的列表迭代器。

常用实现类:

ArrayList:

  • 是一种数组结构的集合,便于查找,增删麻烦
  • 也有一些新增的方法,但貌似不太重要,有兴趣的查文档吧。
import java.util.ArrayList;
import java.util.Iterator;
public class ListDemo {
  public static void main(String[] args) {
    ArrayList q=new ArrayList();
    //增
    q.add("a");
    q.add("b");
    ArrayList a=new ArrayList();
    a.addAll(q);
    a.add("c");
    a.add("d");
    System.out.println(a);//[a, b, c, d],实现了toString,所以可以直接打印出来。
    //删
//    a.remove("a");
    a.remove(0);
    //查
    System.out.println(a.size());//3
    System.out.println(a.contains("b"));//true
    System.out.println(a.isEmpty());//false
    System.out.println(a);//[b, c, d]
    //改
    a.set(0, "bag");
    System.out.println(a);
    //使用迭代器迭代
    for(Iterator it=a.iterator();it.hasNext();) {
      System.out.println(it.next());//c d
    }

  }

}

LinkedList:

  • 是一种链表结构的集合,便于增删,查找不快。
  • 它的元素插入法是头插法,所以后面的元素会排在前面。
  • LinkedList还实现了Deque接口,可以用LinkedList来实现堆栈、队列、双端队列。
  • 因为使用了头插法,所以有几个方法需要注意一下:
    • addFirst(x):将指定元素插入此列表的开头
    • addLast(x):将指定元素添加到此列表的结尾。
    • getFirst():返回此列表的第一个元素。
    • getLast():返回此列表的最后一个元素。
    • removeFirst():移除并返回此列表的第一个元素。
    • removeLast():移除并返回此列表的最后一个元素。
    • descendingIterator():返回逆序的迭代器

补充:

  • 以前还能见到Vector和Stack,但Vector太过古老,被ArrayList取代,所以这里不讲;而Stack已经被ArrayDeque取代。
  • 这里不讲述线程同步中集合的处理。
  • 对于想在迭代器迭代过程中针对集合进行增删改的,可以通过返回ListIterator来操作。

set

介绍:

  • Set是一个接口,定义的是存储的元素是无序的集合,
  • 实现Set的集合中元素不可以重复。
  • 获取Set集合中的元素只能依靠迭代器。

新增方法:无新增方法,基本都是Collection中声明的方法。

常用实现类:

HashSet:

  • 哈希表结构的集合
  • 利用哈希表结果构成的集合查找速度会很快。

TreeSet:

  • 二叉树结构的集合
  • 二叉树插入元素是有顺序的,TreeSet的元素是有序的。
  • 由于二叉树需要对结点排序(插入的结点位置),默认情况下没有排序方法,所以元素需要继承Comparator并重写compareTo方法来实现元素之间比较大小的功能。
  • 对于TreeSet,compareTo方法来保证元素的唯一性。【这时候可以不重写equals】

LinkHashSet:

  • 是HashSet的子类,是链表跟哈希表的数据结构的结合,上一个元素会存储下一个元素的位置,所以可以按顺序来取出。

解决集合的元素的重复:

  • Set集合是不允许重复元素的,但是集合是不知道我们对象的重复的判断依据的,默认情况下判断依据是判断两者是否为同一元素(euqals方法,依据是元素==元素?),如果要依据我们自己的判断来判断元素是否重复,需要重写元素的equals方法(元素比较相等时调用)【在hastSet中还需要多一步:hashCode方法(元素生成hash码的规则,生成的哈希码如果相同则会影响存储规则--》首先判断哈希码是否相同,再判断元素是否相同,如果元素相同则不存储,如果不相同则依据哈希规则向后取一个位置存储(数据结构的知识,这里不讲述))】
  • hashCode()的返回值是元素的哈希码,如果两个元素的哈希码相同,那么需要进行equals判断。【所以可以自定义返回值作为哈希码】
  • equals()返回true代表两元素相同,返回false代表不同。
import java.util.HashSet;
import java.util.Set;
class Student{
  String name;
  int age;
  Student(String name,int age){
    this.name=name;
    this.age=age;
  }
  public String toString() {//重写方法,以便sysout能输出
    return "Student [name=" + name + ", age=" + age + "]";
  }
  public int hashCode() {//这里使用的是自动生成的代码,也可以使用自己的规则
    final int prime = 31;
    int result = 1;
    result = prime * result + age;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
  }
  public boolean equals(Object obj) {//这里使用的是自动生成的代码,也可以使用自己的规则
    if (this == obj)//如果两个地址相同,返回true
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Student other = (Student) obj;
    if (age != other.age)
      return false;
    if (name == null) {
      if (other.name != null)
        return false;
    } else if (!name.equals(other.name))//这里根据姓名和年龄来判断元素是否相同
      return false;
    return true;
  }

}

public class HashSetDemo {

  public static void main(String[] args) {
    Set s=new HashSet();
//    s.add("abc");
//    s.add("abc");
//    System.out.println(s);//这里因为可以使用自带的判断方法,所以不会发生重复

//    s.add(new Student("lilei",18));
//    s.add(new Student("lilei",18));
//    System.out.println(s);//这里因为判断两个地址是不同的,所以会重复。

//    在重写equals之后:
    s.add(new Student("lilei",18));
    s.add(new Student("lilei",18));
    System.out.println(s);//不发生重复。

  }

}

解决TreeSet的排序问题:

  • 二叉树需要结点排序,所以元素之间比较能够比较,所以对于自定义元素对象,需要继承Comparator并重写的compareTo方法。
  • 两个元素相等时,compareTo返回0;左大于右时,返回正整数(一般返回1);小于时返回负整数(一般返回-1)
  • 在TreeSet中,compareTo负责检测元素重复,所以要对compareTo的重写留心。
  • import java.util.TreeSet;
    class Student2 implements Comparable{
      String name;
      int age;
      Student2(String name,int age){
        this.name=name;
        this.age=age;
      }
      public int compareTo(Object o) {
         Student2 stu=(Student2)o;
    
        return this.name.equals(stu.name)?this.age-stu.age:this.name.compareTo(stu.name);
         //默认按姓名排序,如果有重复的姓名,按年龄排序。认为同名同年龄为同一元素
      }
      @Override
      public String toString() {
        return "Student2 [name=" + name + ", age=" + age + "]";
      }
    
    }
    public class TreeSetDemo {
      public static void main(String[] args) {
        TreeSet t=new TreeSet();
    //    t.add("a");
    //    t.add("c");
    //    t.add("d");
    //    t.add("b");
    //    System.out.println(t);//对于非自定义对象,可以排序[a, b, c, d]
        t.add(new Student2("lilei",18));
        t.add(new Student2("lilei",17));
        t.add(new Student2("hanmeimei",18));
        t.add(new Student2("john",17));
        t.add(new Student2("mike",27));
        t.add(new Student2("alice",21));
        System.out.println(t);
      }
    }

  • 还支持创建集合时传入一个比较器Comparator来进行排序,这时候重写的是compare方法:
import java.util.Comparator;
import java.util.TreeSet;
class CompareByLength implements Comparator{

  public int compare(Object o1, Object o2) {

    Student3 stu1=(Student3)o1;
    Student3 stu2=(Student3)o2;
    return stu1.name.length()-stu2.name.length();
//    注意,这里也与compareTo类似,定义的规则必须要考虑到重复性,不然会导致属性值相同的元素
//    认为是同一元素
  }

}

class Student3 {
  String name;
  int age;
  Student3(String name,int age){
    this.name=name;
    this.age=age;
  }
  public String toString() {
    return "Student2 [name=" + name + ", age=" + age + "]";
  }
}
public class TreeSetDemo2 {
  public static void main(String[] args) {

    TreeSet t=new TreeSet(new CompareByLength());
    t.add(new Student3("aaa",18));
    t.add(new Student3("a",18));
//    t.add(new Student3("d",18));//这里是元素重复性的检测,原因在compare
    t.add(new Student3("aa",17));
    t.add(new Student3("cccccccccc",17));
    System.out.println(t);
  }
}


Map:

介绍:

  • Map主要用于存储带有映射关系的数据(比如学号与学生信息的映射关系)
  • Map的存储形式是键值对,一个键对应一个值。
  • 键是不可重复的,值是可以重复的。

常见方法:

  • 获取:

    • keySet():获取所有键,返回一个Set集合
    • get(x):返回指定键x所映射的值;如果此映射不包含该键的映射关系,则返回 null
    • size():返回键值对的数量。
    • values():获取所有值,返回一个Set集合 。
    • entrySet():返回一个集合,集合中的对象都是包含键值对关系的entry类对象。
  • 设置:
    • put(key,value):将指定的值与此映射中的指定键关联【已有则覆盖旧值】
    • putAll(X):从指定映射X中将所有映射关系复制到此映射中。
  • 删除:
    • clear():删除所有键值对 。
    • remove(key):如果存在一个键key的映射关系,则将其从此映射中移除
  • 其他:
    • containsKey(x):检测是否存储指定键x
    • containsValue(x):检测是否存储指定值x
    • isEmpty():检测是否为空,空则返回 true

重要实现类:

HashMap:

  • 哈希表结构的。
  • HashMap的方法基本都是Map中声明的方法

TreeMap:

  • 二叉树结构的。
  • 有序的,可以根据键值来排序,需要实现可以进行比较的方法(compareTo或compare)

Properties:

  • 一种经常用来存储配置的集合,很适合存储一些比如"backgroundColor=red"的数据。
  • 常用方法:
    • getProperty(String key):用指定的键在此属性列表中搜索属性。
    • load(InputStream inStream):从输入流中读取属性列表(键和元素对)。
    • list(PrintStream out):将属性列表输出到指定的输出流。

嵌套类:

Map.Entry<K,V>

  • Map.entrySet 方法配合,Map.entrySet返回的结果是一个集合,集合中的每一个元素都是这个类的对象。
  • 存在意义是返回结果包含了键和值,使得能够同时操作键和值。
  • 此类对象的常用方法:
    • getKey():返回与此项对应的键。
    • getValue():返回与此项对应的值。
    • setValue(value):用指定的值替换与此项对应的值
public class MapDemo {
  public static void main(String[] args) {
    Map m=new HashMap();
    m.put("hanmeimei", "lilei");
    m.put("wodeta", "wo");
    m.put("apple", "google");
    Set s=m.entrySet();
    for(Iterator it=s.iterator();it.hasNext();) {
      Map.Entry me=(Entry) it.next();
      System.out.println(me.getKey()+"...."+me.getValue());
    }
  }
}


Collections工具类:

介绍:

  • Collections是jdk提供的一个专门用来操作集合的类
  • 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。

常用方法:

  • 排序:

    • sort(L):根据元素的自然顺序 对指定列表按升序进行排序。
    • sort(L,C):根据指定比较器C产生的顺序对指定列表进行排序。
  • 查找:

    • max(L):根据元素的自然顺序,返回给定 collection 的最大元素
    • max(L,C):根据指定比较器C产生的顺序,返回给定 collection 的最大元素
    • min(L):根据元素的自然顺序,返回给定 collection 的最小元素
    • min(L,C):根据指定比较器C产生的顺序,返回给定 collection 的最小元素
  • 修改:

    • fill(L,x):使用指定元素替换指定列表中的所有元素。
    • swap(L,indexX,indexY):将指定集合中indexX与indexY的元素交换
    • reverse(L):反转指定列表中元素的顺序。
    • reverseOrder():返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序
import java.util.ArrayList;
import java.util.Collections;
public class ListDemo2 {
  public static void main(String[] args) {
    ArrayList q=new ArrayList();
    q.add("a");
    q.add("z");
    q.add("b");
    q.add("c");
    System.out.println(Collections.max(q));
    System.out.println(q);
    Collections.sort(q);
    System.out.println(q);

  }
}

想了解更多,可以自行查看jdk文档。

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • java集合框架的体系结构详细说明

    最近在一本J2EE的书中看到了很不错的对集合框架的说明文章,筛选后发上来和大家共享,集合框架提供管理对象集合的接口和类.它包含接口,类,算法,以下是它的各个组件的说明. Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同的元素而另一些不行.一些能排序而另一些不行.Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自

  • Java集合Set、List、Map的遍历方法

    本文实例讲述了Java集合Set.List.Map的遍历方法,分享给大家供大家参考. 具体方法如下: package com.shellway.javase; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.uti

  • java集合求和最大值最小值示例分享

    复制代码 代码如下: package com.happyelements.athene.game.util; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Collection; import com.google.common.collect.Lists; /** * Math工具类 *  * @version 1.0 * @since 1.0 */public class M

  • Java判断2个List集合是否相等(不考虑元素的顺序)

    现在有两个对象,他们的一个属性是list,很明显两个对象的list里面的对象,都是相等的,只是这2个list里面的顺序不一致,导致这2个对象被判断为不相等啦,这就是问题,现在要解决这个问题. 问题图如下: 可以看到这2个对象的呢个list属性里面数据,咱看起来是一样的,但是经过equals之后,返回的是false. 所以,需要自己重写equals方法和hashcode方法,这2个方法一般是一起重写的. 然后,问题的关键就在于,怎么判断2个list集合是否相等.不考虑顺序. 看代码: 先是这2个对

  • java实现列表、集合与数组之间转化的方法

    本文实例讲述了java实现列表.集合与数组之间转化的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: package test;  import java.util.ArrayList;  import java.util.Arrays;  import java.util.HashSet;  import java.util.List;  import java.util.Set;  public class Test2 {      public static void

  • java如何对map进行排序详解(map集合的使用)

    今天做统计时需要对X轴的地区按照地区代码(areaCode)进行排序,由于在构建XMLData使用的map来进行数据统计的,所以在统计过程中就需要对map进行排序. 一.简单介绍Map 在讲解Map排序之前,我们先来稍微了解下map.map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等.其中这四者的区别如下(简单介绍): HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接

  • java集合迭代器Iterator中的remove陷阱

    package TestList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.TreeSet; public class TestIterator { /**      * @param args      */     public static void main(String[] args) {         // TODO Auto-gen

  • java中List集合及其遍历详解

    1. 首先List<E>集合继承与Collection<E>,是一个接口. ①  Collection (集合框架是JDK1.2版本出现的) ②   list:是有序的,元素可以重复,以为该集合体系有索引.    经常用到的是实现该接口的ArrayList和LinkedList类 ③   Arraylist:  底层的数据结构使用的是数组结构, 特点: 查询速度很快,但是增删稍慢.线程不同步 LinkedList: 底层使用的是链表数据结构. 特点: 增删速度很快,查询稍慢. Ve

  • Java中对List集合的常用操作详解

    目录: 1.list中添加,获取,删除元素: 2.list中是否包含某个元素: 3.list中根据索引将元素数值改变(替换): 4.list中查看(判断)元素的索引: 5.根据元素索引位置进行的判断: 6.利用list中索引位置重新生成一个新的list(截取集合): 7.对比两个list中的所有元素: 8.判断list是否为空: 9.返回Iterator集合对象: 10.将集合转换为字符串: 11.将集合转换为数组: 12.集合类型转换: 备注:内容中代码具有关联性. 1.list中添加,获取,

  • java集合map取key使用示例 java遍历map

    复制代码 代码如下: for (Iterator i = keys.iterator(); i.hasNext()        {           String key = (String) i.next();           String value = (String) map.get(key);           text+=key + " = " + value;       } 复制代码 代码如下: <span style="border-coll

  • Java实现Map集合二级联动示例

    Map集合可以保存键值映射关系,这非常适合本实例所需要的数据结构,所有省份信息可以保存为Map集合的键,而每个键可以保存对应的城市信息,本实例就是利用Map集合实现了省市级联选择框,当选择省份信息时,将改变城市下拉选择框对应的内容. 思路分析: 1. 创建全国(省,直辖市,自治区)映射集合,即LinkedHashMap对象,使用Map接口的put()方法向集合中添加指定的省与城市的映射关系,其中值为String型一维数组. 代码如下: CityMap.java 复制代码 代码如下: import

随机推荐