Java集合类、List集合与Set集合

一、Java集合类

1.概念

我们都知道Java数组的长度是固定的,在同一个数组中只能存放相同类型的数据。数组既可以存放基本数据类型,也可以存放引用数据类型。但是数组最大的缺陷是长度固定,数组一旦被创建,长度就不能改变。

Java集合引入的目的是:为了使程序能方便地存储和操纵数目不固定的一组数据,JDK类库提供了Java集合。
2.特点

所有的Java集合类都位于java.util包中。和数组不同,Java集合中不能存放基本数据类型,只能存放对象的引用。对于基本数据类型,Java会自动装箱为其对应的包装类。
3.分类
(1)Set(集):集合中的对象不按特定方式排列,并且没有重复的对象。它的有些实现类可以对集合中的对象按特定方式排序。
(2)Link(链表):集合中的对象按照索引位置排序,可以有重复的元素。索引从0开始。
(3)Queue(队列):集合中的元素按照先进先出的规则来排列,在队头删除元素,队尾插入元素。允许有重复的元素。
(4)Map(映射):集合中的每个元素包括一对键(Key)对象和值(Value)对象。集合中没有重复的键对象,允许有重复的值对象。
其中,Set、Link、Queue都是Connection接口的子接口;Map接口没有继承Connection接口。
4.Collection和Iterator接口
 4.1 Collection接口
   下面是一些Collection接口的通用方法。
(1)boolean add(Object o)    向集合中加入一个对象的引用。
(2)void clear()  删除集合中的所有元素,即不再持有对这些对象的引用。
(3)boolean contains(Object o)  判断在集合中是否持有对该对象的引用。
(4)Iterator iterator()   返回一个Iterator对象,可以用它来遍历集合中的元素。
(5)boolean isEmpty()  判断集合是否为空
(6)boolean remove(Object o)  从集合中删除对一个对象的引用。
(7)int size()  返回集合中元素的数目
(8)Object[] toArray()  返回一个对象数组,该数组包含集合中的所有对象。

4.2 Iterator接口
     下面是一些Iterator接口的通用方法。
(1)hasNext():判断集合中是否遍历完毕,如果没有,就返回true.
(2)next():返回下一个元素。
(3)remove():从集合中删除由next()返回的当前元素。
5.集合的输出

集合共有三种输出方式,分别是foreach、Iterator(迭代器)和LinkIterator(双向迭代器)。Iterator方式只能从前向后打印,而LinkIterator方式可以双向打印,但要注意,从后往前打印时一定要先从前向后打印。

public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("hello");
        list.add("hello");
        list.add("bit");


        //方式一  迭代器
        Iterator iterator1 = list.iterator();
        while (iterator1.hasNext()) {
            System.out.print(iterator1.next()+" ");//hello hello bit
        }
     
        //方式二 双向迭代器 ListIterator 可以由后向前输出。要进行由后向前输出时,一定要先进行从前向后输出,否则无法实现双向。
        ListIterator<String> listIterator = ((ArrayList<String>) list).listIterator();
        System.out.println("由前向后输出为:");
        while(listIterator.hasNext()){
            System.out.print(listIterator.next()+" ");
        }
        System.out.println("\n由后向前输出为:");
        while (listIterator.hasPrevious()) {
            System.out.print(listIterator.previous()+" ");
        }
        //结果:由前向后输出为:
        //hello hello bit
        //由后向前输出为:
        //bit hello hello
        System.out.println();
        //方式三  foreach
        for(String mylist:list){
            System.out.print(mylist+" ");//hello hello bit 
        }
    }

 

二、List集合接口

1.List接口较Collection接口扩充的方法是:
      public E get(int index)   根据索引取得数据。
      public E set(int index,E element) 修改数据。
2.特点
    元素以线式方式存储,允许有重复数据。
3.子接口
  3.1 ArrayList接口

ArrayList代表长度可变的数组,允许对元素的随机访问,但是向ArrayList中插入和删除数据的速度较慢。ArrayList类还实现了RandomAccess接口,该接口没有任何方法,仅仅是个标识类型的接口。凡是实现RandomAccess接口的类意味着具有良好的快速随机访问性能。
  3.2 LinkedList接口

实现采用链表数据结构。向LinkedList插入和删除数据的元素较快,但是随机访问的速度较慢。LinkedList单独具有addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等方法,这些方法使得LinkedList可以作为堆栈、队列和双向队列使用。
  3.3 Vector接口(旧的子类)

使用较少,用法和ArrayList类似。Enumeration输出接口只支持Vector接口,而不支持Collection、Set、List等接口。
Enumeration接口的方法有:
    public boolean hasMoreElements();  判断是否有下一个元素
    public E nextElements();   取得元素
    public Enumeration elements()  取得Enumeration对象

代码实现:

public static void main(String[] args) {
        Vector<String> vector=new Vector<>();
        vector.add("hello");
        vector.add("xiaomi");
        vector.add("xiaohong");
        Enumeration<String> enumeration=vector.elements();
        while(enumeration.hasMoreElements()){
            System.out.print(enumeration.nextElement()+" ");
        }
    }

结果:hello xiaomi xiaohong 
 3.4 ArrayList、Vector和LinkedList接口的区别?
     它们三个都是Link接口的子类。
  先比较ArrayList和Vector
   (1)使用时间不同:ArrayList是从JDK1.2提供的,而Vector是从JDK1.0就提供了。
 (2)处理形式不同:ArrayList是异步处理,线程不安全;Vector是同步处理,线程安全。
 (3)数据安全:ArrayList线程不安全;Vector线程安全。
 (4)输出形式:ArrayList支持Iterator、ListIterator、foreach;而Vector支持Iterator、ListIterator、foreach、Enumeration。
  再比较ArrayList和LinkedList
   (1)对数据的操作:ArrayList随机访问的速度块,但是插入和删除的速度慢。
 而LinkedList插入和删除数据的速度快,但是随机访问的速度慢。
 (2)封装的内容不同:ArrayList封装的是数组,而LinkedList封装的是链表。
(3)时间复杂度:ArrayList的时间复杂度是1,而LinkedList的复杂度是n。

4.打印方式

因为Link类中有get()方法,可以直接得到元素。

//List类型的打印
public static void code1(){
    List<String> list=new ArrayList<String>();

    list.add("hello");
    list.add("hello");
    list.add("hello");
    //List类型时有四种输出形式
    //方式一  Collection接口不再适用,因为get()是List子接口提供的。
    for(int i=0;i<list.size();i++){
        System.out.println(list.get(i));
    }
    //方式二
    for(String alist:list){
        System.out.println(alist);
    }
    //方式三  迭代器
    Iterator iterator1=list.iterator();
    while(iterator1.hasNext()){
        System.out.println(iterator1.next());
    }
    //方式四
    System.out.println(list);
}

结果:方式一、二和三输出相同,共输出三行,每行都是hello。

而方式四输出的是:[hello,hello,hello]。

 

5.其它方法
5.1 排序
List只能对集合中的对象按索引位置排序,如果希望对List中的对象按照其它特定方式进行排序,可以借助Collections类和Comparator接口。
如:
    List<Integer> list=new ArrayList<Integer>();
    list.add(1);
    list.add(90);
    list.add(2);

    Collections.sort(list);
    System.out.println(list);//[1,2,90]
5.2删除元素
集合操作Java简单类时,对于remove()和contains()都需要equals()的支持。因此,如果在程序中覆写了equals(),要注意考虑。
     List<Person> personList=new ArrayList<Person>();
     personList.add(new Person("张三",10));
     personList.add(new Person("李四",11));
     personList.add(new Person("王五",12));

     System.out.println(personList);
     System.out.println(personList.remove(new Person("张三",10)));//false,因为这个对象是新new了一个,和原来链表上的不是同一个对象。
     System.out.println(personList);

三、Set集合

1.Set接口并没有对Collection接口进行扩充。因此在Set接口中没有get()。
2.特点
    元素不允许重复。
3.子类
3.1 HashSet
    HashSet类按照哈希算法来存取集合中的对象。HashSet还有子类LinkedHashSet类,它不仅实现了哈希算法,而且实现了链表数据结构,因此提高了插入和删除数据的性能。
3.2 TreeSet
   3.2.1 TreeSet类实现了SortedSet接口,具有排序功能(升序)。

public static void main(String[] args) {
        Set<String> set=new TreeSet<String>();
        set.add("hello");
        set.add("hello");
        set.add("bit");
        //输出方式一
        System.out.println(set+"元素共有:"+set.size()+"个");//[bit, hello]元素共有:2个
        //方式二
        Iterator iterator=set.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+" ");//bit hello 
        }
        System.out.println();
        //方式三
        for(String s:set){
            System.out.print(s+" ");//bit hello 
        }
    }
//如果使用HashSet,则会输出[hello,bit]


 3.2.2 TreeSet的排序分析

TreeSet支持两种排序方式:自然排序和客户化排序,默认情况下使用自然排序(升序)。排序实际上是针对对象数组进行的排序处理,而如果要进行对象数组的排序,对象所在的类一定要是实现Comparale接口并且覆写compareTo(),即客户化排序。
   如

package com.xunpu.collection;

import javax.swing.text.html.HTMLDocument;
import java.util.*;
class Person{
    private String name;
    private int age;
    public Person(String name,int age) {
        this.name = name;
        this.age=age;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
class PersonComparator implements Comparator<Person>{
    @Override//实现逆序
    public int compare(Person o1, Person o2) {
        if(o1.getName().compareTo(o2.getName())>0){
            return -1;
        }
        if(o1.getName().compareTo(o2.getName())<0){
            return 1;
        }
        return 0;
    }
}
public class TestCollection {
    public static void main(String[] args) {
        //创建TreeSet对象时,在构造方法中指定采用PersonComparator来比较Person对象。
        Set<Person> personSet=new TreeSet<Person>(new PersonComparator());
        personSet.add(new Person("张三",10));
        personSet.add(new Person("李四",11));
        personSet.add(new Person("王五",12));
        for(Person p:personSet){
            System.out.println(p.getName()+" "+p.getAge());
        }
    }
}


结果输出:
王五 12
李四 11
张三 10
4.重复元素的判断

TreeSet接口重复元素的判断依靠的是Comparable接口完成的。而HashSet子类,跟Comparable子类没有任何关系,所以它判断重复元素依靠的是Object类中的两个方法:
    hash码:public native int hashCode();
    对象比较:public boolean equals(Object object);
Java中进行对象的比较有两步,首先通过对象的唯一编码找到对象的信息,当编码匹配后,再调用equals()进行内容的比较。
注意:如果要想标识对象的唯一性,一定需要equals()和hashCode()共同调用。
          对象判断必须两个方法equals()、hashCode()返回值都相同时,才能判断相同。

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值