标签:集合类 collections 静态工具类
Collections类提供了一些列静态的方法,用以更方便地操作集合类
排序机制
一个List可以通过下面的方法进行排序:
Collections.sort(list);
如果List包含的是字符串,将会按照字母表排序;如果List包含的是Date类型数据,会按照日期先后排序……这是怎么实现的呢?String和Date都实现了comparable接口,此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo 方法被称为它的自然比较方法。
实现此接口的对象列表(和数组)可以通过Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
对于类 C 的每一个 e1 和 e2 来说,当且仅当e1.compareTo(e2) == 0 与e1.equals(e2) 具有相同的 boolean值时,类 C 的自然排序才叫做与 equals 一致。注意,null 不是任何类的实例,即使e.equals(null) 返回 false,e.compareTo(null) 也将抛出 NullPointerException。
建议(虽然不是必需的)最好使自然排序与equals 一致。这是因为在使用自然排序与 equals 不一致的元素(或键)时,没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。
例如,如果将两个键 a 和 b 添加到没有使用显式比较器的有序集合中,使 (!a.equals(b) && a.compareTo(b) == 0),那么第二个 add 操作将返回 false(有序集合的大小没有增加),因为从有序集合的角度来看,a 和 b 是相等的。
实际上,所有实现 Comparable 的 Java 核心类都具有与equals 一致的自然排序。java.math.BigDecimal 是个例外,它的自然排序将值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)视为相等。
如果试图对一个没有实现comparable接口的类进行排序,会抛出ClassCastException
Comparable接口包含下面的方法:
public interfaceComparable<T> {
public int compareTo(T o);
}
compareTo方法比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
实现类必须确保对于所有的 x 和 y 都存在sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) 的关系。(这意味着如果 y.compareTo(x)抛出一个异常,则 x.compareTo(y) 也要抛出一个异常。)
实现类还必须确保关系是可传递的:(x.compareTo(y)>0&& y.compareTo(z)>0) 意味着 x.compareTo(z)>0。
最后,实现者必须确保x.compareTo(y)==0 意味着对于所有的 z,都存在 sgn(x.compareTo(z)) == sgn(y.compareTo(z))。 强烈推荐(x.compareTo(y)==0) == (x.equals(y)) 这种做法,但并不是严格要求这样做。
在前面的描述中,符号sgn(expression) 指定 signum 数学函数,该函数根据 expression 的值是负数、零还是正数,分别返回 -1、0 或 1 中的一个值。
下面来看一个实例:
public class Name implementsComparable<Name> { private final String firstName, lastName; public Name(String firstName, StringlastName) { if (firstName == null || lastName ==null) throw new NullPointerException(); this.firstName = firstName; this.lastName = lastName; } public String firstName() { return firstName;} public String lastName() { return lastName; } //覆写equals方法 public boolean equals(Object o) { if (!(o instanceof Name)) return false; Name n = (Name) o; return n.firstName.equals(firstName)&& n.lastName.equals(lastName); } //覆写了equals方法则必须覆写hashCode方法,相同的类必须有相同的哈希码 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 nameArray []= { new Name("John","Smith"), new Name("Karl","Ng"), new Name("Jeff","Smith"), new Name("Tom","Rich") }; List<Name> names =Arrays.asList(nameArray); Collections.sort(names); System.out.println(names);
输出:
[Karl Ng, TomRich, Jeff Smith, John Smith]
如果我们不想按照自然排序,而是希望以一种特殊的方式排序呢?这是就需要提供一个Comparator。跟Comparable接口一样,该接口也只包含一个方法:
public interface Comparator<T> { int compare(T o1, T o2); }
Comparator提供了强行对某个对象collection 进行整体排序的比较函数。可以将 Comparator传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
当使用具有与 equals 不一致的强行排序能力的Comparator 对有序 set(或有序映射)进行排序时,应该小心谨慎。假定一个带显式 Comparator c 的有序 set(或有序映射)与从 set S 中抽取出来的元素(或键)一起使用。如果 c 强行对 S 进行的排序是与 equals 不一致的,那么有序 set(或有序映射)将是行为“怪异的”。尤其是有序 set(或有序映射)将违背根据 equals 所定义的 set(或映射)的常规协定。
例如,假定使用 Comparator c 将满足(a.equals(b) && c.compare(a, b) != 0) 的两个元素 a 和 b 添加到一个空TreeSet 中,则第二个 add 操作将返回 true(树 set 的大小将会增加),因为从树 set 的角度来看,a 和 b 是不相等的,即使这与 Set.add 方法的规范相反。
来看一个实例:
public class Employee implements Comparable<Employee> { public Name name() { ... } public int number() { ... } public Date hireDate() { ... } ... }
员工类包含员工的姓名、工号、入职日期等属性,并且实现了Comparable接口,它的自然排序是按照Name来排序的(具体代码见上面的Name类)。假如现在我们不想让它按照Name来排序,而是按照入职日期来排序,利用Comparator来实现:
static final Comparator<Employee> SENIORITY_ORDER = newComparator<Employee>() { public int compare(Employee e1,Employee e2) { //根据入职日期进行排序,本质上还是利用了Date类型的compareTo方法 returne2.hireDate().compareTo(e1.hireDate()); } }; // Employee database static final Collection<Employee>employees = ... ; public static void main(String[] args) { List<Employee> e = newArrayList<Employee>(employees); Collections.sort(e, SENIORITY_ORDER); //传入指定的比较器 System.out.println(e); }
同步“包装”机制
通用的集合类都是线程不安全的,如果需要线程安全的集合类,可以通过Collections类的包装对它们进行转换。
六个核心的接口都有一个静态的工厂方法:
public static <T> Collection<T>synchronizedCollection(Collection<T> c);
public static <T> Set<T> synchronizedSet(Set<T>s);
public static <T> List<T> synchronizedList(List<T>list);
public static <K,V> Map<K,V>synchronizedMap(Map<K,V> m);
public static <T> SortedSet<T>synchronizedSortedSet(SortedSet<T> s);
public static <K,V> SortedMap<K,V>synchronizedSortedMap(SortedMap<K,V> m);
例如,通过下面的这行语句:
List<Type>list = Collections.synchronizedList(new ArrayList<Type>());
我们就得到了一个线程安全的List
在多线程的情况下,使用者在进行迭代的时候需要注意集合的同步状态,推荐的做法是这样:
Collection<Type>c = Collections.synchronizedCollection(myCollection); synchronized(c){ for (Type e : c) foo(e); }
如果使用的是显式迭代器,Iterator方法必须在同步快中调用。对Map的视图进行迭代时也是同样的要求。
Map<KeyType,ValType> m = Collections.synchronizedMap(new HashMap<KeyType,ValType>()); ... Set<KeyType>s = m.keySet(); ... // Synchronizingon m, not s! synchronized(m){ while (KeyType k : s) foo(k); }
方法列表
static <T>boolean addAll(Collection<? superT> c, T... elements)
将所有指定元素添加到指定collection 中。
static <T>int binarySearch(List<? extendsComparable<? super T>> list, T key)
使用二分搜索法搜索指定列表,以获得指定对象。
static <E>Collection<E> checkedCollection(Collection<E>c, Class<E> type)
返回指定 collection 的一个动态类型安全视图。
static <E>List<E> checkedList(List<E>list, Class<E> type)
返回指定列表的一个动态类型安全视图。
static<K,V> Map<K,V> checkedMap(Map<K,V>m, Class<K> keyType, Class<V> valueType)
返回指定映射的一个动态类型安全视图。
static <E>Set<E> checkedSet(Set<E>s, Class<E> type)
返回指定 set 的一个动态类型安全视图。
static<K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V>m, Class<K> keyType, Class<V> valueType)
返回指定有序映射的一个动态类型安全视图。
static <E>SortedSet<E> checkedSortedSet(SortedSet<E>s, Class<E> type)
返回指定有序 set 的一个动态类型安全视图。
static <T>void copy(List<? super T>dest, List<? extends T> src)
将所有元素从一个列表复制到另一个列表。
static boolean disjoint(Collection<?> c1,Collection<?> c2)
如果两个指定 collection 中没有相同的元素,则返回true。
static <T>List<T> emptyList()
返回空的列表(不可变的)。
static<K,V> Map<K,V> emptyMap()
返回空的映射(不可变的)。
static <T>Set<T> emptySet()
返回空的 set(不可变的)。
static <T>Enumeration<T> enumeration(Collection<T>c)
返回一个指定 collection 上的枚举。
static <T>void fill(List<? super T>list, T obj)
使用指定元素替换指定列表中的所有元素。
static int frequency(Collection<?> c, Objecto)
返回指定 collection 中等于指定对象的元素数。
static int indexOfSubList(List<?> source,List<?> target)
返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static int lastIndexOfSubList(List<?>source, List<?> target)
返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
static <T>ArrayList<T> list(Enumeration<T>e)
返回一个数组列表,它按返回顺序包含指定枚举返回的元素。
static <Textends Object & Comparable<? super T>> T max(Collection<?extends T> coll)
根据元素的自然顺序,返回给定collection 的最大元素。
static <Textends Object & Comparable<? super T>> Tmin(Collection<? extends T> coll)
根据元素的自然顺序 返回给定 collection 的最小元素。
static <T>List<T> nCopies(int n, T o)
返回由指定对象的 n 个副本组成的不可变列表。
static <T>boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static void rotate(List<?> list, int distance)
根据指定的距离轮换指定列表中的元素。
static void shuffle(List<?> list)
使用默认随机源对指定列表进行置换。
static <T>Set<T> singleton(T o)
返回一个只包含指定对象的不可变 set。
static <T>List<T> singletonList(T o)
返回一个只包含指定对象的不可变列表。
static<K,V> Map<K,V> singletonMap(Kkey, V value)
返回一个不可变的映射,它只将指定键映射到指定值。
static <Textends Comparable<? super T>> voidsort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
static void swap(List<?> list, int i, int j)
在指定列表的指定位置处交换元素。
static <T>Collection<T> synchronizedCollection(Collection<T>c)
返回指定 collection 支持的同步(线程安全的)collection。
static <T>List<T> synchronizedList(List<T>list)
返回指定列表支持的同步(线程安全的)列表。
static<K,V> Map<K,V> synchronizedMap(Map<K,V>m)
返回由指定映射支持的同步(线程安全的)映射。
static <T>Set<T> synchronizedSet(Set<T>s)
返回指定 set 支持的同步(线程安全的)set。
static<K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V>m)
返回指定有序映射支持的同步(线程安全的)有序映射。
static <T>SortedSet<T> synchronizedSortedSet(SortedSet<T>s)
返回指定有序 set 支持的同步(线程安全的)有序 set。
static <T>Collection<T> unmodifiableCollection(Collection<?extends T> c)
返回指定 collection 的不可修改视图。
static <T>List<T> unmodifiableList(List<?extends T> list)
返回指定列表的不可修改视图。
static<K,V> Map<K,V> unmodifiableMap(Map<?extends K,? extends V> m)
返回指定映射的不可修改视图。
static <T>Set<T> unmodifiableSet(Set<?extends T> s)
返回指定 set 的不可修改视图。
static<K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,?extends V> m)
返回指定有序映射的不可修改视图。
static <T>SortedSet<T> unmodifiableSortedSet(SortedSet<T>s)
返回指定有序 set 的不可修改视图。
标签:集合类 collections 静态工具类
原文地址:http://blog.csdn.net/u012152619/article/details/42674413