集合框架核心接口

来源:互联网 发布:阿里云合作伙伴计划 编辑:程序博客网 时间:2024/06/11 12:57

集合-有时候被称为容器, 就像一手牌(牌的结合),一个邮箱(邮件的集合),或者一个电话簿(姓名和电话对应的关系图)

集合框架核心接口图

  

 

·         Collection对集合核心接口的说明,所有的集合都实现了Collection这个接口,java没有类直接实现了Collection这个接口而是通过更加具体的子接口,比如Set and List

·         Set 不能放重复元素添加重复的元素将毫无用处

·         List 有顺序的集合,可以存放重复的元素

·         Queue 先进先出的集合FIFO (first-in-first-out)

·         Map 用键值对的关系来存储数据,键值不能重复,一个键只能对应一个值

·         SortedSet, SortedMap分别是Setmap的排序版本

Collection 接口:集合框架中的最顶的接口,集合中最抽象的一个接口

·         需要注意的方法:addAll

boolean addAll(Collection c) 将另外一个集合中的所有元素添加到这个集合中,

而如果用add()方法则是把集合C按照一个元素添加进去。

Set 接口:不能放重复的元素的集合。在java中有三种主要的实现

 HashSet, TreeSet, and LinkedHashSet

·         HashSet效率最高,但是不能保证集合里面的元素是按顺序读取的

·         TreeSet 通过所存储的元素的值对元素进行排序,比HashSet

·         LinkedHashSet 通过集合里面的元素插入的时候的顺序进行排序

Eg1

import java.util.*;

public class TestSet {

    public static void main(String args[]) {

        Set s = new HashSet();

        String test[]={"java", "FindDups" ,"i" ,"came", "i", "saw", "i", "left"};

        String a;

        for (int i=0;i<test.length;i++){

       

        a=test[i];

            if (!s.add(a))

                System.out.println("Duplicate: " + a);

        System.out.println(s.size()+" distinct words: "+s);

    }

}

}

需要注意的一点是代码中一直引用的是 (Set)这个接口而不是具体的实现类(HashSet).这样做的好处就是给你的程序带来了很好的适应性。上面的例子中的输出是没有经过排序的,如果你希望进行排序,仅仅把hashset的实现换成treeset就好了

Eg2假设你想知道在一串字符中那些只是出现了一次,那些有重复,并且只是在最后打印结果

可以通过两个set来实现

import java.util.*;

public class FindDups2 {

    public static void main(String args[]) {

        Set<String> uniques = new HashSet<String>();

        Set<String> dups = new HashSet<String>();

 

        for (String a : args)

            if (!uniques.add(a))

                dups.add(a);

 

        //Destructive set-difference

        uniques.removeAll(dups);

        System.out.println("Unique words:    " + uniques);

        System.out.println("Duplicate words: " + dups);

    }

}

Eg3 去掉重复的元素

Monster m=new Monster(i);

       List c=new ArrayList();

       c.add(m);

       c.add(m);

      

       HashSet noDups = new HashSet(c);

       Iterator it=noDups.iterator();

       while(it.hasNext()){

           Monster mon=(Monster)it.next();

           System.out.println();

           System.out.println("new"+mon.toString());

       }

 

List接口是一个有顺序的集合,可以有重复的元素

·         List接口有两种比较常用的实现ArrayList LinkedList

如果两个List 以相同的顺序存储相同的元素那这两个list就是equal

Queue 接口,先进先出的集合FIFO (first-in-first-out)

import java.util.*;

public class Countdown {

    public static void main(String[] args)

            throws InterruptedException {

        int time = Integer.parseInt(args[0]);

        Queue<Integer> queue = new LinkedList<Integer>();

        for (int i = time; i >= 0; i--)

            queue.add(i);

        while(!queue.isEmpty()) {

            System.out.println(queue.remove());

            Thread.sleep(1000);

        }

    }

}

Map 接口用键值对的关系来存储数据,键值不能重复,一个键只能对应一个值Map 的实现类: HashMap , TreeMap , and LinkedHashMap set类似

 Map的基本方法: (put, get, containsKey, containsValue, size, and isEmpty)

Eg1 输入 java Freq if it is to be it is up to me to delegate
 
输出 8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}

 

import java.util.*;

public class Freq {

    public static void main(String args[]) {

        Map<String, Integer>  m =

            new HashMap<String, Integer>();

 

        // Initialize frequency table from command line

        for (String a : args) {

            Integer freq = m.get(a);

            m.put(a, (freq == null ? 1 : freq + 1));

        }

        System.out.println(m.size() + " distinct words:");

        System.out.println(m);

    }

}

 

Object Ordering 对象的顺序

一个 List l可以像下面那样去排序

Collections.sort(l);

如果List 包含String元素,会按照字幕的顺序进行排序。如果包含Date元素会按照日期的顺序进行排序。这是因为String  Date 都实现了Comparable这个接口。Comparable接口提供了类的顺序下面的表是总结了java的一些类实现了这个接口的顺序

Classes Implementing Comparable

Class

Natural Ordering

Byte

Signed numerical

Character

UnSigned numerical

Long

Signed numerical

Integer

Signed numerical

Short

Signed numerical

Double

Signed numerical

Float

Signed numerical

BigInteger

Signed numerical

BigDecimal

Signed numerical

Boolean

Boolean.FALSE < Boolean.TRUE

File

System-dependent lexicographic on path name

String

Lexicographic

Date

Chronological

CollationKey

Locale-specific lexicographic

 

import java.util.*;

public final class Name implements Comparable<Name> {

    private final String firstName, lastName;

   

    public Name(String firstName, String lastName) {

        if (firstName == null || lastName == null)

            throw new NullPointerException();

 

        this.firstName = firstName;

        this.lastName = lastName;

    }

    public String firstName() { return firstName; }

    public String lastName()  { return lastName;  }

    public boolean equals(Object o) {

        if (!(o instanceof Name))

            return false;

        Name n = (Name) o;

        return n.firstName.equals(firstName) &&

            n.lastName.equals(lastName);

    }

    public int hashCode() {

        return 31*firstName.hashCode() + lastName.hashCode();

    }

    public String toString() {

        return firstName + " " + lastName;

    }

    public int compareTo(Name n) {

        int lastCmp = lastName.compareTo(n.lastName);

        return (lastCmp != 0 ? lastCmp :

                firstName.compareTo(n.firstName));

    }

}

·   Name 这个对象是不能变的

·   在构造函数中坚持参数是否是null,这样保证了其他方法不会抛出空指针异常。

·   重新定义 hashCode 方法 (Equal objects must have equal hash codes.)

·   重新定义  equals方法返回false当比较的对象是null 或者是不相符的类型的时候

·   定义toString 方法让它返回能读懂的东西。

 

Comparators

当你想用另外一种方法去排序对象,或者已有的类没有实现Comparable这个接口的时候怎么办呢?

Interface Comparator 出现了,他封装了排序

假设你有一个类叫做 Employee

public class Employee implements Comparable<Employee> {

    public Name name()     { ... }

    public int number()    { ... }

    public Date hireDate() { ... }

       ...

}

假设这个类是通过名字进行排序的,你的老板突然想让你通过入职日期来进行排序

import java.util.*;

class EmpSort {

    static final Comparator<Employee> SENIORITY_ORDER =

                                 new Comparator<Employee>() {

        public int compare(Employee e1, Employee e2) {

            return e2.hireDate().compareTo(e1.hireDate());

        }

    };

 

    //Employee database

    static final Collection<Employee> employees = ... ;

 

    public static void main(String[] args) {

        List<Employee>e = new ArrayList<Employee>(employees);

        Collections.sort(e, SENIORITY_ORDER);

        System.out.println(e);

    }

}

需要注意的地方:compareTo方法一定要小心写,要考虑到需要比较的对象条件是相等的情况。例如如果两个相同日期入职的员工Jackandy 那由于compareTo方法的问题只能有一个人存储到treeset里面

static final Comparator<Employee> SENIORITY_ORDER =
                               new Comparator<Employee>() {
   public int compare(Employee e1, Employee e2) {
      int dateCmp = e2.hireDate().compareTo(e1.hireDate());
      if (dateCmp != 0)
         return dateCmp;
      return (e1.number() < e2.number() ? -1 :
              (e1.number() == e2.number() ? 0 : 1));
   }
};

 

 

 

选择使用那种集合的时候需要考虑 首先是速度,那种最适合,序列化,线程,

·         Arrays 直接是由硬件实现的,速度最快 ArrayList,

·         Linked lists 时候插入和删除操作

·         Hash tables 键值

·         Trees

HashSet 最常用的set通过一个 hash table来实现

General-purpose Implementations

Interfaces

Implementations

 

Hash table

Resizable array

Tree

Linked list

Hash table + Linked list

Set

HashSet

 

TreeSet

 

LinkedHashSet

List

 

ArrayList

 

LinkedList

 

Queue

 

 

 

 

 

Map

HashMap

 

TreeMap

 

LinkedHashMap

原创粉丝点击