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


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

    集合比数组的优势:
        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
  • 相关阅读:
    String类
    数学类
    同一场景下多个图层之间的调用
    茶壶在触摸机制下旋转的三种方式
    犀牛3D模型下载
    纹理--高清设计素材下载
    cocos2d-x-2.x与3.x帧动画实现方式的改变
    toast提示框的实现
    MenuItem创建注意事项
    Cocos2d-x 面试题解 整理01
  • 原文地址:https://www.cnblogs.com/nicker/p/6238163.html
Copyright © 2020-2023  润新知