1、集合框架 java
基于继承特征创建起的体系结构,集合框架至关庞大,首先看图解:
算法
一、集合类出现的缘由:
面向对象的核心就是对象,Java将全部的事物都封装成对象,咱们要操做这些对象,就要将这些对象存储起来,而集合就是存储多个对象的容器。 数组
二、集合类特色:
集合只用于存储对象。集合长度是可变的。集合能够存储不一样类型的对象。 安全
三、集合使用步骤:
1) 建立集合对象。
2) 建立元素对象。
3) 把元素对象添加到集合对象中。
4) 遍历集合对象(经过集合对象获取迭代器对象,经过迭代器对象的 hasNext()方法进行判断,经过迭代器对象的 next()进行获取)。
数据结构
四、数组与集合类同是容器,有何区别?
1) 对象都使用集合存储;数据都使用数组存储。
2) 数组虽然也能够存储对象,但长度是固定的;集合长度是可变长度的。
3) 数组中存储的是同一类对象,还能够存储基本数据类型;集合只能存储对象。
4) 数组存储数据类型是固定的,而集合存储的数据类型不固定。
多线程
2、Collection接口
Collection 是层次结构中的根接口(顶层接口)。有两个经常使用的接口 List 和 Set。在 List接口中有经常使用类 ArrayList、LinkedList 和 Vector;在 Set 接口中有类 HashSet、TreeSet。
一、Collection子类:
List:元素有序,能够重复。(由于有索引)
Set:元素无序,不能够重复。
二、Collection中常见的操做:
添加:
boolean add(E e); //添加指定元素;接收的是一个 Object 类型对象。
boolean addAll(Collection<? extends E> c); //添加集合,一次添加一堆元素。
删除:
void clear( ); //清空容器。移除 Collection 中的全部元素(可操做)
boolean remove(Object o); //移除一个指定元素
boolean removeAll(Collection<? > c); //移除一堆元素。只要有元素被删除,就返回 true。
获取:
int size(); //获取集合长度,若为 0,则为空,没有元素。
判断:
boolean isEmpty(); //若不包含元素,返回 ture。
boolean contains(); //包含指定元素,返回 ture。判断是否含有某个元素。
boolean containsAll(Collection c); //判断是否含有指定集合中的全部元素,只有全部数据都包含才返回 true
其余:
int hashCode( ); //返回此 collection 的哈希码值
Iterator <E> iterator( ); //返回此元素上进行的迭代器,用于遍历集合中的元素
boolean retainAll( ); //取交集。只在调用者中保留共同的交集元素。 并发
三、迭代器:
1)概念:
其实就是集合取出元素的方式,将取出方式定义在集合内部,这样取出方式就能够直接访问集合内部的元素。那么取出方式就定义为了内部类,而根据每一个数据结构的不一样,去除取出方式也不一样,但都有共性内容:判断和取出,那么久抽取出共性内容,将其封装成对象Iterator。 集合均可以使用iterator()方法获取取出对象Iterator。
2)迭代器的常见操做:
hasNext(); //有下一个元素,返回真
next(); //取出下一个元素
remove(); //移除
Note:在迭代时循环中next调用一次,就要hasNext判断一次。
如下代码演示迭代器的使用: app
public class CollectionDemo { public static void main(String[] args) { method_3(); } public static void method_3() { // 建立一个集合容器,使用Collection接口的子类---ArrayList ArrayList al1 = new ArrayList(); // 添加元素 al1.add("demo1"); al1.add("demo2"); al1.add("demo5"); al1.add("demo6"); //获取迭代器,第一种方法 Iterator it1 = al1.iterator(); while (it1.hasNext()) { System.out.println("while::"+it1.next()); } //for循环,迭代器对象随着循环结束而消失,内存开销小,第二种方法 for (Iterator it = al1.iterator(); it.hasNext();) { System.out.println("for::"+it.next()); } } }
结果如图所示:
框架
迭代注意事项:
1) 迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
2) 迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
3) 迭代器的next方法返回值类型是Object,因此要记得类型转换。 ide
3、List
一、List:元素是有序的,元素能够重复。由于该集合体系有索引。
二、List 接口中的特有方法:
add(int index,Object obj); //在指定位置加入元素
remove(int index); //移除指定位置的元素
set(int index,Object obj) ; //修改指定位置的元素
get(int index) ; //获取指定位置的元素
indexOf(Object obj) ; //获取指定元素的位置
subList(int start,int end) ; //从一个大的 List 中截取一个小的 List
三、List 特有迭代器:
ListIterator<E> listIterator( ); //返回列表迭代器。
ListIterator 是 Itertorde 子接口。 在迭代时,不能够经过集合对象的方法操做集合中的元素,容易发生安全隐患;报错:并发修改异常 ConcurrentModificationException。在迭代器时,只能用迭代器的方法操做元素,但是 Iterator 方法是有限的,只能对元素进行判断、取出、删除的操做,若是想要其余的操做如添加,修改等,就须要使用其子接口,ListIterator。该接口只能经过 List 集合的 listIterator 方法获取。
示例以下:
import java.util.ArrayList; import java.util.ListIterator; /* * List集合特有的迭代器ListIterator是Iterator的子接口 * 在迭代时,不能够经过集合对象的方法来操做集合中的元素,由于会发生并发修改异常 */ public class CollectionSub { public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add("java04"); ListIterator li = al.listIterator(); while (li.hasNext()) { Object obj = li.next(); if (obj.equals("java02")) { li.set("java009"); } } System.out.println(al); System.out.println("hasNext?" + li.hasNext()); System.out.println("hasPrevious?" + li.hasPrevious()); } }
四、常见子类对象:
ArrayList:底层的数据结构是数组结构,查询快,增删慢,线程不一样步(长度初始值为10,增量50%)
LinkedList:底层是链表结构,增删快,查询慢
Vector:底层是数组数据结构,线程同步,被ArrayList所取代,(长度初始值为10,增量100%)
1)ArrayList
特有方法: (凡是能够操做角标的方法都是该体系特有的方法)
添加:
void add(int index , E element); //在指定位置插入指定元素。
boolean addAll(int index ,Collection<? extends E> c); //将全部元素插入到列表中指定位置。
删除:
remove(int index); //移除指定位置上的元素
修改:
set(int index, E element); //修改指定索引值上的元素
查询:
get(int index); // 获取位置索引
int indexOf (Object o); //判断位置索引。若是不含该元素,则返回-1.
subList(int fromIndex ,int toIndex); //截取。含头不含尾。
boolean hasPrevious( ); //若是以逆向遍历列表,列表迭代器有多个元素,则返回 true
2)Vector
特有方法:
void addElement(); //添加组件
elementAt(int index); //至关于 get 方法
firstElement(); //获取第一个组件
insertElement(E obj , int index); //插入
last Element(); //最后一个组件
removeAllElements(); //移除
public Enumeration elements(); //返回此向量的组件枚举
枚举就是 Vector 特有的取出方式。枚举和迭代是同样的,但枚举的名称和方法的名称都过长,因此就被迭代器取代了。
枚举 Enumeration 的方法摘要:
boolean hasMoreElements(): 测试此枚举是否包含更多的元素。
E nextElement(): 若是此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
Enumeration 是一个接口,此接口的功能与 Iterator 接口的功能是重复的。 此外, Iterator接口添加了一个移除操做,并使用较短的方法名。新的实现应该优先考虑 Iterator 接口,而不是 Enumeration 接口。
示例以下:
/* * Vector特有的去除方式--枚举Enumeration * 枚举和迭代都是同样的 */ import java.util.Enumeration; import java.util.Vector; public class VectorDemo { public static void main(String[] args) { Vector v = new Vector<>(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en = v.elements(); while (en.hasMoreElements()) { System.out.println(en.nextElement()); } } }
3)LinkedList
特有方法:
void addFirst( ); //在此列表的开头插入指定的元素。
void addLast( );
getFirst(); //获取元素,但不删除元素
getLast();
removeFirst(); //获取元素,但删除元素,容量减小
removeLast(); //当集合中没有元素时,使用上面的方法会出现没有这个元素异常NoSuchElementException
JDK1.6 版本出现下面代替方法:
boolean offerFirst(); //在此列表的开头插入指定的元素。
boolean offerLast(); //在此列表末尾插入指定的元素。
peekFirst(); // 获取元素,但不删除元素。若是集合中没有元素,会返回 null。
peekLast();
pollFirst(); // 获取元素,可是元素被删除。若是集合中没有元素,会返回 null。
pollLast();
演示以下:
import java.util.LinkedList; /* * LinkedList特有方法演示: */ public class LinkedListDemo { public static void main(String[] args) { LinkedList ll = new LinkedList(); ll.addFirst("java01"); ll.addLast("java01"); ll.addLast("java02"); ll.addLast("java03"); ll.addLast("java04"); System.out.println(ll.removeFirst()); System.out.println(ll.getLast()); System.out.println("长度:" + ll.size()); while (!ll.isEmpty()) { System.out.println(ll.pollFirst()); } } }
4、Set
一、概述:
Set:元素是无序(存入和取出的顺序不必定一致),元素不能够重复。Set 继承一个不包含重复元素的 Collection。Set 集合的功能和 Collection 是一致的。特色:惟1、无序、不重复。
HashSet: 底层数据结构是哈希表。元素惟1、线程不安全,非同步。但效率高。容许使用 null。元素。不保证迭代顺序,特别是它不保证该顺序恒久不变。
TreeSet: 底层数据结构是二叉树。能够对 Set 集合中的元素进行排序。
二、HashSet
HashSet:数据结构是哈希表,线程是非同步。
哈希表:根据哈希算法存储的,存储的就是对象的哈希值。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类容许使用 null 元素。
保证元素惟一性的原理:判断元素的 hashCode 值是否相同。若相同,会继续判断元素的 equals 方法,是否为 true。
示例以下:
import java.util.HashSet; import java.util.Iterator; /* * HashSet: * HashSet 中的 add 方法都作了什么? * 添加集合元素,同时会调用 hashCode 方法,在内存中造成对象的哈希值。 * HashSet 中特有的 add 方法 (add 的返回值是 boolean 类型的) 自动调用 equals 方法: * 首先判断元素的 hashCode 值是否相同。若不一样,直接添加元素。若相同,会继续判断 * 元素的 equals 方法,元素相同返回 false,不添加元素;元素不一样,返回 true,添加元素。 * Tips:对于判断元素是否存在以及删除等操做,都是依赖于hashCode和equals方法 */ class Person { private String name; private int age; Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @Override public int hashCode() { System.out.println(this.name + "...hashCode"); return name.hashCode() + age * 39; } @Override public boolean equals(Object obj) { if (!(obj instanceof Person)) { return false; } Person p = (Person) obj; System.out.println(this.name + "...equals..." + this.age); return this.name.equals(p.getName()) && this.age == p.getAge(); } } public class SetDefine { public static void main(String[] args) { HashSet hs = new HashSet<>(); hs.add(new Person("zhangsan", 12)); hs.add(new Person("li", 15)); hs.add(new Person("li", 15)); hs.add(new Person("wangwu", 23)); hs.add(new Person("zhaoliu", 25)); System.out.println(hs.contains(new Person("li", 15))); System.out.println(hs.remove(new Person("li", 15))); Iterator it = hs.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }结果如图所示:
2)TreeSet
特色:
1) 底层的数据结构为二叉树结构(红黑树结构)
2) 可对Set集合中的元素进行排序,是由于:TreeSet类实现了Comparable接口,该接口强制让增长到集合中的对象进行了比较,须要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。
Note:排序时。当主要条件相同时,必定要判断一下次要条件。
Comparable:此接口强行对实现它的每一个类的对象进行总体天然排序,使元素具有比较性
Comparator:强行对某个对象 collection 进行总体排序的比较函数,使集合具有比较性
TreeSet 排序的第一种方式:
让元素(集合)自身具有比较性。元素须要实现 Comparable 接口,覆盖 compareTo 方法。这种方式也成为元素的天然顺序,或者叫作默认顺序。基本数据类型或字符串对象均实现了 Comparable 接口,故同种类型基本数据间具有比较性,即天然顺序。
TreeSet 排序的第二种方式:
当元素自身不具有比较性时,或者具有的比较性不是所须要的。这时就须要让集合自身具有比较性。定义比较器,将比较器对象做为参数传递给TreeSet 构造函数。在集合初始化时,就有了比较方式。利用 TreeSet(Comparator Comparator); 构造方法构造一个新的空 TreeSet,它根据指定比较器进行排序。Comparator 是一个接口,接口中有两个方法:
int compare(T o1,T o2); //比较用来排序的两个参数。
Boolean equals(Object o); //指示某个其余对象是否等于此“Comparetor”。
Note:当两种排序都存在时,以比较器为主。
示例以下:
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; /* * TeeSet:能够对Set集合的元素排序 * 底层的数据结构是二叉树保证元素的惟一性,依赖于compareTo方法 * 排序方式: * 一、让元素自身具有比较性,元素须要实现Comparable接口覆盖compareTo方法,完成天然排序的默认顺序 * 二、当元素自身不具有比较性或者具有的比较性并不是所须要的,此时要让集合自身具有比较性.定义比较器,将比较器对象做为参数传递给TreeSet构造函数。 * 两种方法排序是以比较器为主 */ class Student implements Comparable { // 强制让学生具有比较性 private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Object o) { // TODO Auto-generated method stub if (!(o instanceof Student)) { throw new RuntimeException("不是学生对象!!!"); } Student stu = (Student) o; return (this.age - stu.getAge()) == 0 ? this.name.compareTo(stu .getName()) : (this.age - stu.getAge()); } } // 比较器 class myComparator implements Comparator { @Override public int compare(Object o1, Object o2) { // TODO Auto-generated method stub Student stu1 = (Student) o1; Student stu2 = (Student) o2; int nameOff = stu1.getName().compareTo(stu2.getName()); return nameOff == 0 ? stu1.getAge() - stu2.getAge() : nameOff; } } public class TreeSetDemo { public static void main(String[] args) { TreeSet t = new TreeSet(new myComparator()); t.add(new Student("zhangsan", 24)); t.add(new Student("li", 23)); t.add(new Student("wangwu", 23)); t.add(new Student("zhaoliu", 23)); t.add(new Student("zhaoliu", 25)); Iterator it = t.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }结果以下所示:
5、Map<K,V>接口
一、Map 集合: 该集合存储键值对,成对存入,保证键的惟一性。map 将键映射到值的对象。键值对之间用等号(=)链接。Map 和 Set 很像,Set 集合底层就是使用了 Map 集合。(K: 表明此映射所维护的键的类型 V: 表明映射值的类型)
二、Map集合子类:
|--Hashtable 底层是哈希表结构,不能够存入null键null值,线程是同步的
|--HashMap 底层是哈希表结构,容许使用null键null值,线程不一样步效率高
|--TreeMap 底层是二叉树结构,线程不一样步,能够用于给map集合中的键进行排序
三、Map集合经常使用方法:
添加:
V put(K key, V value); //将指定的值与此映射中的指定键关联
Note:当 key 在集合中不存在时,添加元素;当 key 在集合存在的时,替换元素。即若添加时出现相同的键,那么新添加的值会覆盖原有的键对应值,而且 put 方法会返回所被覆盖的值。
删除:
clear(); //移除全部键值对数据
V remove(Object key); // 移除;根据指定键删除键值对。
Note: 当不存在该键时,返回值为 null;若存在该键, 则删除该键,并返回该键所对应的值。
判断:
boolean containsValue(Object value);//判断指定值是否在集合中存在,若此映射将一个或多个键映射到指定值返回true。
boolean containsKey(); //判断指定键是否在集合中存在。若此映射包含指定键的映射关系,则返回 true。
boolean isEmpty(); //判断集合是否为空。若此映射未包含键、值映射关系,则返回 true。
获取:
Collection<V> values();//获取 map 集合中全部的值。获取元素值,V 表明键值类型
V get(Object key); //根据键获取值。返回指定键所在的值,若不存在该键,则返回 null。
Note:能够经过 get()方法的返回值来判断一个键是否存在。经过返回 null 来判断。
void putAll(); //从指定映射中将全部映射关系复制到此映射中
int size(); // 获取长度
演示以下:
import java.util.HashMap; import java.util.Map; /* * Map:存储的是键值对,而且保证了键的惟一性 * 一、添加元素 * put() * putAll() * 二、删除元素 * clear() * remove() * 三、判断 * boolean containsKey() * boolean containsValue() * 四、获取 * get() * size() * values() * * Map: * |--Hashtable 底层是哈希表结构,不能够存入null键null值,线程是同步的 * |--HashMap 底层是哈希表结构,容许使用null键null值,线程不一样步效率高 * |--TreeMap 底层是二叉树结构,线程不一样步,能够用于给map集合中的键进行排序 */ public class MapDemo1 { public static void main(String[] args) { // TODO Auto-generated method stub Map<String, String> map = new HashMap<String, String>(); // 添加元素是若是出现相同的键,那么后添加的值会覆盖原有键对应的值,而且put方法会返回被覆盖的值 map.put("001", "zhangsan1"); System.out.println(map.put("001", "lisi")); map.put("002", "zhangsan2"); map.put("003", "zhangsan3"); System.out.println("containsKey---" + map.containsKey("002")); // System.out.println("remove---" + map.remove("003")); // 能够经过get方法的返回值来判断一个键是否存在 map.put("004", "not null"); System.out.println("get---" + map.get(null)); // 获取map集合中全部的值,返回值Collections System.out.println("values---" + map.values()); System.out.println(map); } }结果如图所示:
四、Map集合元素的获取:
由于Map中没有迭代器,因此只能先用自有方法将元素转移到有迭代器集合中再逐个迭代取出。此处有两种方法:
1)Set<k> keyset() //返回全部键的集合。
原理:将 map 集合转成 set 集合,再经过迭代器取出。返回此映射中包含的键的 Set 视图;也就是将 map 中的全部键都存到 Set 集合中。由于:set 具有迭代器。因此能够经过迭代方式取出全部的键,再根据 get()方法获取每个键所对应的值。
步骤:
a) 先获取 map 集合的全部键的 Set 集合,经过 keySet()方法;
b) 获取迭代器,取得 map 全部键。而后经过 map 集合的 get()方法获取元素对象的值。
2)set<Map.Entry<K,V>> entrySet() //键值对对象的结合。返回此映射中包含的映射关系的 Set 视图。
原理:将 Map 集合中的映射关系存入到 Set 集合中。这个映射关系的数据类型是Map.entry,再经过 Map.Entry 类的方法再要取出关系里面的键和值,Map.Entry<K,V>是一个静态接口,能够理解为一种映射关系。
Note:Map.Entry<K,V>是一个静态接口,能够理解为一种映射关系。Map.Entry 被封闭在 Map 接口中。其实 Entry 也是一个接口,表明一种映射关系。Entry 是 Map 接口中的一个内部接口。Map.Entry<K,V>中有如下方法:
boolean equals(); //比较指定对象与此项的相等性
getKey(); //返回与此项对应的键
getValue(); //返回与此项对应的值
int hashCode(); //返回此映像的哈希码值
setValue(value); //用指定的值替换对应的值
3)步骤:
a) 将 Map 集合中的映射关系取出,存入 Set 集合中。
b) 经过 Map.Entry 类的方法再要取出关系里面的键和值
两种元素取出方式演示以下:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /* * Map键值对取出方式: * 一、keySet: * 将map中全部的键存入Set集合中,由于Set集合有迭代器,利用迭代器取出key在利用map的get()方法获取键对应的值 * 二、Set<Map.Entry<k,v>> entrySet: * 将Map集合中的映射关系取出存入到Set集合中,再利用Set的迭代器获取键值对 * */ public class MapDemo2 { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("01", "zhangsan1"); map.put("02", "zhangsan2"); map.put("03", "zhangsan3"); map.put("04", "zhangsan4"); System.out.println("第一种方式取出"); Set<String> mapSet = map.keySet(); Iterator<String> itSet = mapSet.iterator(); while (itSet.hasNext()) { String key = itSet.next(); System.out.println(key + "--itSet--" + map.get(key)); } System.out.println("第二种方式取出"); Set<Map.Entry<String, String>> entrySet = map.entrySet(); Iterator<Map.Entry<String, String>> itEntrySet = entrySet.iterator(); while (itEntrySet.hasNext()) { Map.Entry<String, String> me = itEntrySet.next(); System.out.println(me.getKey() + "--itEntrySet--" + me.getValue()); } } }结果以下所示:
四、Map集合的拓展及应用:
1)Hashtable: 底层是哈希表的数据结构,不能够存入 null 键 null 值。线程同步。
此类实现一个哈希表,该哈希表将键映射到相应的值。 任何非 null 对象均可以用做键或值。 在哈希表中存储和获取对象, 用做键的对象必须实现 hashCode()方法和 equals()方法(以能保证键的惟一性)。
2)HashMap: 基于哈希表的 map 接口实现,底层是哈希表的数据结构,并容许使用 null值、null 键,该集合线程不一样步、无序。
保证元素惟一性的原理: 先判断元素的 hashCode 值是否相同,再判断两元素的 equals方法是否为true(往 HashSet 里面存的自定义元素要复写 hashCode 和 equals 方法,以保证元素的惟一性)。
3)TreeMap: 底层是二叉树数据结构。线程不一样步,能够用于给 map 集合中的键进行排序,其实 Set 底层就使用了 Map 集合。
应用实例以下:
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; /* * "asdadgaadgfgjnknckjnfvcxvergccxk"获取字符串中的自摸出项的次数 * 打印结果为:a(2) b(3) ... * * 一、将字符串转换成字符数组 * 二、定义一个Map集合 * 三、遍历字符数组。 * 将每个元素做为键去查Map集合 * 若是返回值为null,将该子母和1存入到Map中 * 若是返回不是null,则说明该字母出现过,将该字母对应的值自增1再存入Map中 * 四、按照指定格式打印出来 */ public class MapTest3 { public static void main(String[] args) { // TODO Auto-generated method stub String str = "asdadgaadgf--===gjnknckjnfvcxvergccxk"; String result = charCount(str); System.out.println(result); } public static String charCount(String str) { //将字符串变成字符数组 char[] chs = str.toCharArray(); TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>(); int count = 0;//定义计数器 for (int i = 0; i < chs.length; i++) { //剔除非字母字符 if (!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z')) { continue; } Integer value = tm.get(chs[i]); if (value != null) { count = value; } count++; tm.put(chs[i], count); count = 0;//每次循环后都将计数器置为零 /* * if (value == null) { tm.put(chs[i], 1); } else { tm.put(chs[i], * ++value); } */ } // System.out.println(tm); //定于StringBuilder存放结果 StringBuilder sb = new StringBuilder(); Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet(); Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator(); while (it.hasNext()) { Map.Entry<Character, Integer> me = it.next(); Character ch = me.getKey(); Integer in = me.getValue(); sb.append(ch + "(" + in + ")"); } return sb.toString(); } }
结果以下所示:
6、工具类
一、Collections: 集合框架的工具类。里面定义的都是静态方法。
Collections 和 Collection 有什么区别?
Collection: 是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个经常使用的子接口,List:对元素都有定义索引。有序的。能够重复元素。Set:不能够重复元素。无序。
Collections: 是集合框架中的一个工具类。该类中的方法都是静态的。此类彻底由在 collection上进行操做或返回 collection 的静态方法组成。提供的方法中有能够对 list 集合进行排序,二分查找等方法。一般经常使用的集合都是线程不安全的。由于要提升效率。若是多线程操做这些集合时,能够经过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
特色:方法都是静态的,不须要建立对象。
public static <T extends Comparable <? Super T>> void sort(List<T> list) //排序。
max(); //返回最大元素
binarySearch(); //二分法查找,前提必须是有序集合。
fill(); //能够将 list 集合中全部元素替换成指定元素。 也能够将 list 集合中部分元素替换成指定元素。
replaceAll(); //替换,按元素替换
reverse(); //反转
reverseOrder(); //反向排序,能够强行逆转比较器
swap(); //置换
shuffle(); //随机排序
集合有一个共同的缺点,那就是线程不安全,被多线程操做时,容易出现问题,虽然能够本身加锁,可是麻烦。Collections 提供特牛的方法,就是给它一个不一样步的集合,它返回一个同步的安全的集合。
synchronizdMap(); //返回指定列表支持的同步(线程安全的)映射。
synchronizdList(); //返回指定列表支持的同步(线程安全的)列表。
synchronizedSet(); //返回指定列表支持的同步(线程安全的)集合Set。
示例以下:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.TreeSet; /* * 集合框架工具类: * Collections:全部的方法都是静态的 * 一、排序方法: * static <T extends Comparator<? super T>> void sort(List<T> list) * staitc void sort(List<T> list,Comparator<? super T> com) */ class StringLngthComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { // TODO Auto-generated method stub return o1.length() - o2.length() == 0 ? o1.compareTo(o2) : o1.length() - o2.length(); } } public class CollectionsDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("ijk"); list.add("abcabc"); list.add("fgh"); list.add("cdef"); list.add("lmn"); Collections.sort(list, new StringLngthComparator()); System.out.println(list); sortDemo(list); maxDemo(list); // 练习:将list集合中部分元素替换成指定元素 fillDemo(list, "aa"); replaceDemo(list, "fgh", "fff"); System.out.println(list); reverseOrderDemo(); shuffleDemo(); } private static void shuffleDemo() { List<String> shu = new ArrayList<String>(); shu.add("a"); shu.add("ab"); shu.add("fgh"); shu.add("cdef"); shu.add("zzzzzz"); System.out.println(shu); Collections.shuffle(shu); System.out.println(shu); } public static void reverseOrderDemo() { TreeSet<String> set = new TreeSet<String>(Collections.reverseOrder()); set.add("a"); set.add("ab"); set.add("fgh"); set.add("cdef"); set.add("zzzzzz"); System.out.println(set); } public static void replaceDemo(List<String> list, String oldString, String newString) { Collections.replaceAll(list, oldString, newString); } public static void fillDemo(List<String> list, String str) { Collections.fill(list, str); } public static void maxDemo(List<String> list) { System.out.println("Max=" + Collections.max(list, new StringLngthComparator())); } public static void sortDemo(List<String> list) { System.out.println(list); Collections.sort(list, new StringLngthComparator()); System.out.println(list); } }
二、Arrays: 用于操做数组的工具类,里面都是静态方法。
Lsit<T> asList(T... a) //将数组变成 list 集合,可使用集合的思想和方法来操做数组中的元素。
copyOfRange(); //将指定数组复制到新的数组。
equals(); //比较数组元素是否彻底相同
deepEquals(); //比较数组元素,而且比较元素内容是否相同。
fill(); //替换数组中的元素,还能够替换数组中的范围。
sort(); //排序
toString(); //转化成字符形式
Note:
a)将数组变成集合,不可使用集合的增删方法。不然会发生不支持操做异常(UnsupportedOperationException)。
b)若是数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
c)若是数组中的元素都是基本数据类型,那么会将该数组做为集合中的元素存在。
示例以下:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* * Arrays: * * 数组变集合 * asList(T... a) * 一、将数组变成集合目的是便于使用集合的方法操做,可是不能增删不然会出现UnsupportionException * 二、若是数组中的元素都是对象,则直接转成集合中的元素 * 三、若是数组中的元素都是基本数据类型,那么回将数组做为集合中的元素 * * 集合变数组 * toArray() */ public class ArraysDemo { public static void main(String[] args) { // TODO Auto-generated method stub asListDemo(); toArrayDemo(); } private static void toArrayDemo() { ArrayList<String> al = new ArrayList<String>(); al.add("abc1"); al.add("abc2"); al.add("abc3"); al.add("abc4"); /* * 一、指定类型的数组初始长度: -- 当指定数组的长度小于了集合的长度,那么方法内部会从新建立一个新的数组长度和集合同样 * 当指定的数组长度大于集合的长度,那么就直接使用传递进来的数组 二、为何将集合变数组:-- 为了限定对集合元素的操做 */ String[] arr = al.toArray(new String[5]); System.out.println(Arrays.toString(arr)); } public static void asListDemo() { String[] arr = { "abc", "efg", "xyz" }; int[] ar = { 1, 2, 3 }; List<String> listStr = Arrays.asList(arr); System.out.println("Contains---" + listStr.contains("abc")); List<int[]> list = Arrays.asList(ar); System.out.println(list); } }
本篇幅所描述的仅表明我的见解,若有出入请见谅。