Dev_Nick

导航

集合(二)------单列集合

集合:集合是存储对象数据的集合容器。

集合比数组的优势:
    1. 集合可以存储任意类型的对象数据,数组只能存储同一种数据类型 的数据。
    2. 集合的长度是会发生变化的,数组的长度是固定的。

单列集合体系:

---------| Collection 单例集合的根接口
------------| List  如果是实现了List接口的集合类, 具备的特点:有序,重复。
---------------| ArraryList  底层 是使用了Object数组实现的,特点: 查询速度快,增删慢。
---------------| LinkedList 底层是使用了链表数据结构实现 的, 特点: 查询速度慢,增删快。
---------------| Vector Vector的实现与ArrayList是一致,但是是线程安全 的,操作效率低。 jdk1.0的时候出现的
------------| Set  如果是实现了Set接口的集合类,具备的特点:无序,不可重复。
----------------| HashSet  底层是使用了一个哈希表支持的, 特点:存取速度快。

----------------| TreeSet  底层是使用了红黑树(二叉树)数据结构实现的, 特点:会对元素进行排序存储。

 

凡是容器都具有增删改查的功能和对应的方法。

collection接口中的方法:

增加:

boolean add(E e)  确保此 collection 包含指定的元素(可选操作)。

boolean addAll(Collection<? extends E> c)  将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。

删除:

void clear() 移除此 collection 中的所有元素(可选操作)。

boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。

boolean removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。

boolean retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。

查看:

int size() 返回此 collection 中的元素数。

判断:

boolean isEmpty()  如果此 collection 不包含元素,则返回 true

boolean contains(Object o) 如果此 collection 包含指定的元素,则返回 true

boolean containsAll(Collection<?> c)   如果此 collection 包含指定 collection 中的所有元素,则返回 true

迭代:

Object[] toArray()  返回包含此 collection 中所有元素的数组。

Iterator<Eiterator() 返回在此 collection 的元素上进行迭代的迭代器。

迭代器的方法:

boolean hasNext() 如果仍有元素可以迭代,则返回 true

E  next()  返回迭代的下一个元素。

void remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。只能用在调用next方法之后,否则会报异常:java.lang.IllegalStateException

代码示例如下:

 1 import java.util.ArrayList;
 2 import java.util.Arrays;
 3 import java.util.Collection;
 4 import java.util.Iterator;
 5 
 6 public class DemoCollection {
 7 
 8     public static void main(String[] args) {
 9         //加入
10         Collection<String> collection = new ArrayList<String>();
11         System.out.println("加入元素是否成功?"+ collection.add("张三"));
12         collection.add("李四");
13         System.out.println("add之后的collection"+collection);
14         
15         Collection<String> collection2 = new ArrayList<String>();
16         collection2.add("王五");
17         collection2.add("赵六");
18         collection.addAll(collection2);
19         System.out.println("addAll之后的collection"+collection);
20         //删除
21         System.out.println("删除是否成功?"+collection2.remove("赵六1"));
22         System.out.println("删除是否成功?"+collection2.remove("赵六"));
23         System.out.println("remove之后的collection2"+collection2);
24         System.out.println("删除是否成功?"+collection.removeAll(collection2));
25         System.out.println("removeAll之后的collection"+collection);
26         
27         Collection<String> collection3 = new ArrayList<String>();
28         collection3.add("赵六");
29         System.out.println("删除是否成功?"+collection.retainAll(collection3));
30         System.out.println("retainAll之后的"+collection);
31         
32         collection2.clear();
33         System.out.println("clear之后的collection2?"+collection2);
34         //查看
35         System.out.println("collection的元素个数:"+collection.size());
36         //判断
37         System.out.println("collection时候为空?"+collection.isEmpty());
38         System.out.println("collection是否包含赵六?"+collection.contains("赵六"));
39         System.out.println("collection是否包含collection3?"+collection.containsAll(collection3));
40         //迭代
41         Object[] array = collection.toArray();
42         System.out.println(Arrays.toString(array));
43         
44         Iterator<String> iterator = collection.iterator();
45         while (iterator.hasNext()) {
46             System.out.println(iterator.next());
47         }
48         
49         Iterator<String> iterator2 = collection.iterator();
50         iterator2.next();
51         iterator2.remove();
52         System.out.println("collection中的"+collection);
53     }
54     
55 }
View Code


List接口特有的方法:

增加:

void add(int index, E element) 在列表的指定位置插入指定元素(可选操作)。

boolean addAll(int index, Collection<? extends E> c)  将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

修改:

E set(int index, E element)  用指定元素替换列表中指定位置的元素(可选操作)。

查看:

E get(int index) 返回列表中指定位置的元素。

int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。

int lastIndexOf(Object o) 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。

List<E> subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

迭代器:

ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按适当顺序)。

ListIterator<E> listIterator(int index) 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

ListIterator接口特有的方法:

boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true

E previous() 返回列表中的前一个元素。

void add(E e)  将指定的元素插入列表(可选操作)。意思是把当前有元素插入到当前指针指向的位置上。

void set(E e) 用指定元素替换 nextprevious 返回的最后一个元素(可选操作)。

迭代器在变量元素的时候要注意事项:

1、在迭代器迭代元素 的过程中,不允许使用集合对象改变集合中的元素 个数,如果需要添加或者删除只能使用迭代器的方法进行操作。
 
2、如果使用过了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常。    
 
迭代元素的过程中: 迭代器创建到使用结束的时间。

代码示例如下:

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 import java.util.ListIterator;
 4 
 5 public class DemoList {
 6     public static void main(String[] args) {
 7         List<String> list = new ArrayList<String>();
 8         //增加
 9         list.add(0, "张三");
10         System.out.println(list);
11         List<String> list2 = new ArrayList<String>();
12         list2.add("李四");
13         list2.add("王五");
14         list.addAll(1, list2);
15         System.out.println(list);
16         //修改
17         list.set(2, "赵六");
18         System.out.println(list);
19         //查看
20         System.out.println("索引为0的元素:"+list.get(0));
21         System.out.println("李四的索引为:"+list.indexOf("李四"));
22         list.add("张三");
23         System.out.println("张三的索引为:"+list.indexOf("张三"));
24         System.out.println("张三最后一次出现的索引为:"+list.lastIndexOf("张三"));
25         
26         List<String> list3 = list.subList(1, 3);
27         System.out.println(list3);
28         
29         //迭代器
30         System.out.println(list);
31         ListIterator<String> listIterator = list.listIterator();
32         while(listIterator.hasNext()){
33             listIterator.add("哈哈");
34             System.out.print(listIterator.next()+",");
35 //            listIterator.set("=="); //只能用在next或者previous之后
36         }
37         System.out.println();
38         System.out.println(list);
39         while(listIterator.hasPrevious()){
40             list.remove("张三"); //在迭代中不能修改List,否则会报异常ConcurrentModificationException
41             System.out.print(listIterator.previous()+",");
42         }
43     }
44 }
View Code

 

ArrayList类特有的方法:

void ensureCapacity(int minCapacity)  如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。

void trimToSize() 将此 ArrayList 实例的容量调整为列表的当前大小。

注意:ArrayList底层是维护了一个Object数组实现 的,使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长0.5倍。

需求: 编写一个函数清除集合中重复书籍,书号相等即为重复。

代码如下:

 1 import java.util.ArrayList;
 2 import java.util.ListIterator;
 3 
 4 class Book{
 5     int id;
 6     String name;
 7     public Book(int id, String name) {
 8         this.id = id;
 9         this.name = name;
10     }
11     
12     @Override
13     public boolean equals(Object obj) {
14         Book book = (Book) obj;
15         return this.id == book.id;
16     }
17     @Override
18     public int hashCode() {
19         return this.id;
20     }
21     
22     @Override
23     public String toString() {
24         return "[编号:"+this.id +"书名:"+this.name+"]";
25     }
26 }
27 
28 
29 public class DemoList {
30     public static void main(String[] args) {
31         ArrayList<Book> list = new ArrayList<Book>();
32         list.add(new Book(110, "西游记"));
33         list.add(new Book(220, "水浒传"));
34         list.add(new Book(110, "西门庆与潘金莲"));
35         System.out.println(list);
36         System.out.println(clearRepeat(list));
37     }
38     
39     public static ArrayList<Book> clearRepeat(ArrayList<Book> arrayList) {
40         ArrayList<Book> newList = new ArrayList<Book>();
41         ListIterator<Book> listIterator = arrayList.listIterator();
42         while(listIterator.hasNext()){
43             Book book = listIterator.next();
44             if (!newList.contains(book)) {
45                 newList.add(book);
46             }
47         }
48         return newList;
49     }
50 }
View Code

 LinkList类特有的方法:

增加:

void addFirst(E e) 将指定元素插入此列表的开头。

void addLast(E e)  将指定元素添加到此列表的结尾。

删除:

E removeFirst() 移除并返回此列表的第一个元素。

E removeLast() 移除并返回此列表的最后一个元素。

查看:

E getFirst() 返回此列表的第一个元素。

E getLast() 返回此列表的最后一个元素。

逆序迭代器:

Iterator<E> descendingIterator() 返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。

与数据结构相关的函数:

1:栈 (1.6)  : 主要是用于实现堆栈数据结构的存储方式。
      先进后出
      void push(E e) 将元素推入此列表所表示的堆栈。
      E pop() 从此列表所表示的堆栈处弹出一个元素。
2:队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
      先进先出
      boolean offer(E e)  将指定元素添加到此列表的末尾(最后一个元素)。
      E poll()  获取并移除此列表的头(第一个元素)

代码示例如下:

 1 public class DemoList {
 2     public static void main(String[] args) {
 3         LinkedList<String> list = new LinkedList<String>();
 4         //增加
 5         list.add("李四");
 6         list.addFirst("张三");
 7         list.addLast("王五");
 8         System.out.println(list);
 9         //查看
10         System.out.println(list.getFirst());
11         System.out.println(list.getLast());
12         //逆序构造器
13         Iterator<String> iterator = list.descendingIterator();
14         while(iterator.hasNext()){
15             System.out.println(iterator.next());
16         }
17         //删除
18         list.removeLast();
19         System.out.println(list);
20         list.removeFirst();
21         System.out.println(list);
22         //与数据结构
23         //
24         list.push("战三");
25         System.out.println(list);
26         list.pop();
27         System.out.println(list);
28         //队列
29         list.offer("张三");
30         System.out.println(list);
31         list.poll();
32         System.out.println(list);
33         
34     }
35 }
View Code


需求:使用LinkedList实现堆栈数据结构的存储方式与队列的数据结构存储方式。   

代码如下:

 1 class StackList<T>{
 2     LinkedList<T> list;
 3 
 4     public StackList() {
 5         this.list = new LinkedList<T>();
 6     }
 7     
 8     public void push(T t) {
 9         this.list.addFirst(t);
10     }
11     
12     public T pop() {
13         return this.list.removeFirst();
14     }
15     
16     @Override
17     public String toString() {
18         return list.toString();
19     }
20     
21 }
22 
23 class QueueList<T>{
24     LinkedList<T> list;
25 
26     public QueueList() {
27         this.list = new LinkedList<T>();
28     }
29     
30     public boolean offer(T t) {
31         return this.list.offer(t);
32     }
33     
34     public T poll() {
35         return this.list.poll();
36     }
37     @Override
38     public String toString() {
39         return this.list.toString();
40     }
41 }
42 
43 public class DemoList {
44     public static void main(String[] args) {
45         StackList<String> stackList = new StackList<String>();
46         stackList.push("张三");
47         stackList.push("李四");
48         stackList.push("王五");
49         System.out.println(stackList);
50         stackList.pop();
51         System.out.println(stackList);
52         
53         QueueList<String> queueList = new QueueList<String>();
54         queueList.offer("张三");
55         queueList.offer("李四");
56         queueList.offer("王五");
57         System.out.println(queueList);
58         queueList.poll();
59         System.out.println(queueList);
60         
61     }
62 }
View Code

需求: 使用LinkedList存储一副扑克牌,然后实现洗牌功能。

 1 //扑克类
 2 class Poker{
 3     
 4     String  color; //花色
 5     String num;    //点数
 6 
 7     public Poker(String color, String num) {
 8         super();
 9         this.color = color;
10         this.num = num;
11     }
12 
13     @Override
14     public String toString() {
15         return "{"+color+num+"}";
16     }
17 }
18 
19 public class Demo2 {
20     
21     public static void main(String[] args) {
22         LinkedList pokers = createPoker();
23         shufflePoker(pokers);
24         showPoker(pokers);
25     }
26     
27     //洗牌的功能
28     public static void shufflePoker(LinkedList pokers){
29         //创建随机数对象
30         Random random = new Random();
31         for(int i = 0 ; i <100; i++){ 
32             //随机产生两个索引值
33             int index1 = random.nextInt(pokers.size());
34             int index2 = random.nextInt(pokers.size());
35             //根据索引值取出两张牌,然后交换两张牌的顺序
36             Poker poker1 = (Poker) pokers.get(index1);
37             Poker poker2 = (Poker) pokers.get(index2);
38             pokers.set(index1, poker2);
39             pokers.set(index2, poker1);
40         }
41     }
42     
43     //显示扑克牌
44     public static void showPoker(LinkedList pokers){
45         for(int i = 0 ; i<pokers.size() ; i++){
46             System.out.print(pokers.get(i));
47             //换行
48             if(i%13==12){
49                 System.out.println();
50             }
51         }
52     }
53     
54     //生成扑克牌的方法
55     public static LinkedList createPoker(){
56         //该集合用于存储扑克对象。
57         LinkedList list = new LinkedList();        
58         //定义数组存储所有的花色与点数
59         String[] colors = {"黑桃","红桃","梅花","方块"};
60         String[] nums = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
61         for(int i = 0 ; i < colors.length ; i++){
62             for(int j = 0 ; j<nums.length ; j++){
63                 list.add(new Poker(colors[i], nums[j]));
64             }
65         }
66         return list;
67     }
68 }
View Code

笔试题: 说出ArrayLsit与Vector的区别?
    相同点: ArrayList与Vector底层都是使用了Object数组实现的。
    不同点:
        1. ArrayList是线程不同步的,操作效率高。
           Vector是线程同步的,操作效率低。
        2. ArrayList是JDK1.2出现,Vector是jdk1.0的时候出现的。

set接口没有特有的方法

set中的元素是无序不可重复的。

hashSet的实现原理:底层是使用了一个哈希表支持的。

往Haset添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,然后通过元素 的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。存储过程中有一下两种情况。
     情况1: 如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
   情况2: 如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不添加,如果equals方法返回的是false,那么该元素允许添加。

需求:接受键盘录入用户名和密码来进行用户注册。如果用户名和密码已经存在,则不能完成注册。如果不存在,则注册成功。

代码示例如下:

 1 import java.util.HashSet;
 2 import java.util.Scanner;
 3 
 4 //接受键盘录入用户名和密码来进行用户注册。如果用户名和密码已经存在,则不能完成注册。如果不存在,则注册成功。
 5 class User{
 6     String userName;
 7     String password;
 8     public User(String userName, String password) {
 9         this.userName = userName;
10         this.password = password;
11     }
12     
13     @Override
14     public int hashCode() {
15         // 如果两个字符串的内容一致,那么返回的hashCode 码肯定也会一致的。
16         return this.userName.hashCode() + this.password.hashCode();
17     }
18     
19     @Override
20     public boolean equals(Object obj) {
21         User user = (User)obj;
22         return this.userName.equals(user.userName) && this.password.equals(user.password);
23     }
24     
25     @Override
26     public String toString() {
27         
28         return "当前用户名:"+this.userName + "密码:"+this.password;
29     }
30     
31 }
32 
33 public class Set {
34     public static void main(String[] args) {
35         Scanner scanner = new Scanner(System.in);
36         HashSet<User> set = new HashSet<User>();
37         while(true){
38             System.out.println("请输入账号:");
39             String userName = scanner.next();
40             System.out.println("请输入密码:");
41             String password = scanner.next();
42             User user = new User(userName, password);
43             
44             if (set.add(user)) {
45                 System.out.println("注册成功");
46                 System.out.println(set);
47             }else{
48                 System.out.println("注册失败");
49             }
50         }
51     }
52 }
View Code

treeSet

内部实现:

  底层是使用了红黑树(二叉树)数据结构实现的, 特点:会对元素进行排序存储

注意事项:

   1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
     2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素
     的比较规则定义在compareTo(T o)方法上。
     3. 如果比较元素的时候,compareTo方法返回 的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)
     4. 往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
     5.  往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器,那么是以比较器的比较规则优先使用。

如何自定义定义比较器:

  自定义一个类实现Comparator接口即可,把元素与元素之间的比较规则定义在compare方法内即可。
自定义比较器的格式 :
             class  类名  implements Comparator{
             }
     
推荐使用:使用比较器(Comparator)。

TreeSet存储具备自然顺序的元素,代码示例如下:

 1 public class Set {
 2     
 3     public static void main(String[] args) {
 4         TreeSet<Integer> treeSet = new TreeSet<Integer>();
 5         treeSet.add(1);
 6         treeSet.add(10);
 7         treeSet.add(8);
 8         treeSet.add(3);
 9         treeSet.add(2);
10         System.out.println(treeSet);
11     }
12 }
View Code

TreeSet存储不具备自然顺序的元素,代码示例如下:

当前类实现Comparable接口和public int compareTo(Object o)方法

 1 class User implements Comparable<User>{
 2     Integer id;
 3     String userName;
 4     String password;
 5     public User(Integer id, String userName, String password) {
 6         this.id = id;
 7         this.userName = userName;
 8         this.password = password;
 9     }
10     
11     @Override
12     public int compareTo(User o) {
13         User user = (User)o;
14         return this.id - user.id;
15     }
16     
17     @Override
18     public String toString() {
19         return "id:"+ this.id +"  名字:"+this.userName ;
20     }
21     
22 }
23 
24 public class Set {
25     
26     public static void main(String[] args) {
27         TreeSet<User> treeSet = new TreeSet<User>();
28         treeSet.add(new User(110, "张三", "123"));
29         treeSet.add(new User(310, "王五", "123"));
30         treeSet.add(new User(210, "李四", "123"));
31         System.out.println(treeSet);
32     }
33 }
View Code

自定义比较器类

 1 class User{
 2     Integer id;
 3     String userName;
 4     String password;
 5     public User(Integer id, String userName, String password) {
 6         this.id = id;
 7         this.userName = userName;
 8         this.password = password;
 9     }
10     
11     @Override
12     public String toString() {
13         return "id:"+ this.id +"  名字:"+this.userName ;
14     }
15     
16 }
17 
18 class myComparator implements Comparator<User>{
19     
20     @Override
21     public int compare(User o1, User o2) {
22         return o1.id - o2.id;
23     }
24 }
25 
26 public class Set {
27     
28     public static void main(String[] args) {
29         TreeSet<User> treeSet = new TreeSet<User>(new myComparator());
30         treeSet.add(new User(110, "张三", "123"));
31         treeSet.add(new User(310, "王五", "123"));
32         treeSet.add(new User(210, "李四", "123"));
33         System.out.println(treeSet);
34     }
35 }
View Code

 

posted on 2016-12-31 14:42  Dev_Nick  阅读(1133)  评论(0编辑  收藏  举报