A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Dream丿拼 中级黑马   /  2018-5-3 17:00  /  1339 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Java集合

数组作为容器,可以存储基本数据类型,也可以存储引用数据类型,数组一旦定义出来,长度就固定了,而且也只能存储引用数据类型,用起来不太方便,所以就引出了集合的概念。
集合
集合的长度是可变的,集合中可以存储不同的数据类型,但是集合不能存储基本数据类型
集合中的方法

        Collection:     包括      list     和 set

a/添加功能
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):添加一个集合的元素  (给一个集合添加进另一个集合中的所有元素)
[Java] 纯文本查看 复制代码
Collection con = new ArrayList();  
       con.add(s1);  
       con.add(s2);  
       con.add(s3);  
Collection con2 = new ArrayList();  
       con2.add(Integer.valueOf(1));  
       con2.add(2);  
       con2.add(3);  
       con.addAll(con2); 

b/删除功能
   void clear():移除所有元素
   boolean remove(Object o):移除一个元素
   boolean removeAll(Collection c):移除一个集合的元素(移除一个以上返回的就是true) 删除的元素是两个集合的交集元素 ,如果没有交集元素 则删除失败 返回false
[Java] 纯文本查看 复制代码
    Collection collection = new ArrayList();  
    <span class="space" style="white-space:pre;display:inline-block;text-indent:2em;line-height:inherit;">    </span>collection.add("关羽");  
           collection.add("张飞");  
           collection.add("赵云");  
           collection.add("马超");  
           collection.add("魏延");  
           boolean b = collection.remove("魏延");  

[Java] 纯文本查看 复制代码
<span style="background-color:transparent;">   </span>A 集合 removeAll B 集合,如果两个集合没有交集元素,则移除失败  
   两个集合中的元素都不会发生变化  
   如果说有交集元素, A 集合 removeAll B 集合 那么A中就会移除掉 交集元素 B集合不发生变化,移除成功 

c/判断功能   boolean contains(Object o):判断集合中是否包含指定的元素
   boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含 才返回true)
   boolean isEmpty():判断集合是否为空

d/获取功能,接口 Iterator<E> 迭代器(可以理解为遍历)

boolean hasNext()
如果仍有元素可以迭代,则返回 true
[Java] 纯文本查看 复制代码
    Iterator iterator = collection.iterator();  
                while (iterator.hasNext()){  
                Object next = iterator.next();  
                System.out.println(next);}  

e/长度功能
      int size():元素的个数
f/交集功能
   A集合对B集合取交集,获取到的交集元素在A集合中。返回的布尔值表示的是A集合是否发生变化
   boolean retainAll(Collection c):获取两个集合的交集元素(交集:两个集合都有的元素)

g/把集合转换为数组

    toArray( )        System.out.println(collection.size());
[Java] 纯文本查看 复制代码
    Collection collection = new ArrayList();  
           collection.add(1);  
           collection.add(2);  
           collection.add(3);  
           collection.add(4);  
           collection.add(5);  
           collection.add(6);  
     Object[] toArray();  
           Object[] objects = collection.toArray();  

但是要注意的是通过aslist方法把数组转换成集合后,这个集合就不能再添加元素了
[Java] 纯文本查看 复制代码
    Integer[] integers = {1, 2, 3, 7};  
            List<Integer> integers1 = Arrays.asList(integers);  
            // integers1.remove(1);//报错  
            //integers1.add(6);//报错  

Collection 集合 对应一个工具类  Collections
[Java] 纯文本查看 复制代码
    ArrayList<Integer> list = new ArrayList<>();  
            list.add(3);  
            list.add(6);  
            list.add(5);  
            list.add(2);  
            list.add(1);  
            list.add(9);  
            list.add(10);  
            Comparator<Integer> comparator = new Comparator<Integer>() {  
                @Override  
                public int compare(Integer s1, Integer s2) {  
                    return s1 - s2;  
                }  
            };  
            //Lambda 表达式 需要 函数式接口的支持,使用Lambda表达式可以有效的的节省代码,但应用时一定要细心将表达式补充完整。  
            //函数式接口 接口里面只有一个抽象方法就是函数式接口  
            // Comparator<Integer> com = (x, y) -> x - y;  
          //Lambda 表达式 要一种函数式接口的支持                              排序  
            list.sort(comparator);  
            Collections.sort(list);  
            System.out.println(list);  
    二分查找,前提是集合的元素有序  
            int i = Collections.binarySearch(list, 10);  
            System.out.println(i);  
    获取集合中 最大值和最小值  
            Integer max = Collections.max(list);  
            Integer min = Collections.min(list);  
    反转集合中的元素  
            Collections.reverse(list);  
            System.out.println(list);  
    随机打乱集合中的元素顺序  
            Collections.shuffle(list);  
            System.out.println(list);  

接口 Iterator<E>

通过迭代器是遍历集合的一种方式
boolean hasNext()
        如果仍有元素可以迭代,则返回 true。
        next()
        返回迭代的下一个元素。
[Java] 纯文本查看 复制代码
    Iterator iterator = collection.iterator();  
           while (iterator.hasNext()){  
               Object next = iterator.next();  
System.out.println(next);}  

获取集合长度的方法 size()System.out.println(collection.size());

虽然集合可以存储任意数据的引用数据类型但一般来说,我们不会给集合中存储的多种类型的元素,我们一般只在集合里面就存储一种类型
List集合:  包括  ArrayList       Vector         LinkedList允许元素重复
  void add(int index,E element): 在指定索引处添加元素
  E remove(int index):移除指定索引处的元素  返回的是移除的元素
  E get(int index):获取指定索引处的元素
  E set(int index,E element):更改指定索引处的元素 返回的而是被替换的元素
  subList(首索引,尾索引),根据首位索引截取集合中的元素
List的三个子类的特点 ArrayList  底层数据结构是数组,增删慢,查询快  线程不同步,数据不安全,效率高
Vector 底层数据结构也是数组,增删慢 查询快 线程同步,数据安全,效率慢
LinkedList 底层数据结构是链表,增删快 查询慢 线程不同步,数据不安全效率高
我们根据需要,如果对数据安全要求较高,建议采用Vector
还要考虑操作中查询多还是增删多
数组特点: 查询快 , 增删慢
链表特点:  查询慢 , 增删快




ListIteratorListIterator继承了Iterator,所以也可以使用Iterator中的方法
而ListIterator的特有功能有
  boolean hasPrevious():   是否存在前一个元素
  E previous():     返回列表中的前一个元素
用这两个方法反向遍历集合
因为指针默认在集合开始,只有先将指针放到末尾才能反向遍历
[Java] 纯文本查看 复制代码
    ListIterator<String> iterator = list.listIterator();  
          while (iterator.hasNext()){  
              System.out.println( iterator.next());  
          }  
          System.out.println("---------------------");  
              while (iterator.hasPrevious()){  
              System.out.println(iterator.previous())  


List集合的遍历方式
如果说你用迭代器去遍历集合,在遍历的中间,如果你想往集合里面加元素,或者说删除元素
那就要用迭代器自己的 添加和删除方法,不要用集合的添加和删除方法,不然就会报并发修改异常,//ConcurrentModificationException,所以经常采用for循环来遍历
[Java] 纯文本查看 复制代码
方式1:  
     Iterator<String> iterator = list.iterator();  
     while (iterator.hasNext()) {  
  
         System.out.println(iterator.next());  
     }  
     System.out.println("----------------------------------------");  
方式2:采用List 特有的迭代器  
     ListIterator<String> stringListIterator = list.listIterator();  
     while (stringListIterator.hasNext()) {  
         System.out.println(stringListIterator.next());  
  
     }  
     System.out.println("----------------------------");  
方式3:for 循环遍历//我们最常用for循环来遍历  
     for (int i = 0; i < list.size(); i++) {  
         System.out.println(list.get(i));  
  
     } 


ArrayList他的底层数据结构是数组,所以 查询快,增删慢
数据是有序的,存的顺序和取得顺序一样

[Java] 纯文本查看 复制代码
    ArrayList<String> list = new ArrayList<>();  
          list.add("唐三藏");  
          list.add("孙大圣");  
          list.add("猪悟能");  
          list.add("沙悟净");  
          list.add("小白龙");  
          list.add("唐三藏");  
          list.add("孙大圣");  
          list.add("猪悟能");  
          list.add("沙悟净");  
          list.add("小白龙");  
          //重新拿出一个集合,遍历第一个集合,去掉重复的元素  
          ArrayList<String> newList = new ArrayList<>();  
          for (int i = 0; i < list.size(); i++) {  
              String ele = list.get(i);  
              if (!newList.contains(ele)) {  
                  newList.add(ele);  
              }  
          }  
          System.out.println(newList);  
          System.out.println(list);  

其中contains这个方法底层调用了equals方法,默认比较的是地址值,所以当两个对象相同时,我们要重写equals方法

VectorinsertElementAt(E obj, int index)在指定索引的位置插入一个元素
indexOf(Object o)返回指定元素的一次出现的索引

lastElement()获取集合中最后一个元素
firstElement()获取集合中第一个元素
Vector 特有的一个遍历方式
        Enumeration<String> elements = v.elements();
       boolean hasMoreElements()
        测试此集合是否包含更多元素。
        E nextElement()
       返回此集合的下一个元素,如果此集合至少有一个元素可以返回。
LinkedListvoid addFirst(E e)在此列表的开始处插入指定的元素。
void addLast(E e)将指定的元素列表的结束。
getFirst()返回此列表中的第一个元素。
getLast()返回此列表中的最后一个元素。
boolean offer(E e)将指定的元素添加到列表的尾部(最后一个元素)。
boolean offerFirst(E e)在列表的前面插入指定的元素。
boolean offerLast(E e)在列表的结尾插入指定的元素。
void push(E e)将一个元素放在集合最前端


Arrays工具类的asList()方法将数组元素转换成集合,得到的集合长度是不可变的 你不能往这个转换后的集合中 添加元素(add) 和 删除元素(remove), 只能获取元素(get)

数据结构的栈和队列


数据结构的数组和链表

set接口:包含HashSet   LinkedHashSet     TreeSetset集合的特点:元素是无序的,唯一的HashSet(无序,唯一)HashSet集合底层结构是哈希表,哈希表底层维护的是数组和链表
HashSet集合靠元素重写hashCode和equals方法来保证元素的唯一性
元素有序靠链表保证
元素唯一靠哈希表保证
如果元素不重写这两个方法,就无法保证唯一性
String和Integer默认重写了hashCode方法和equals方法
HashSet存储元素保证元素唯一性图解

TreeSet(排序,唯一)TreeSet  底层数据结构是二叉树结构,元素唯一,而且还能排序

二叉树存储数据保证元素唯一性的原理图解



排序的方法有两种
1。自然排序   空参构造采用的就是自然排序
采用自然排序,是元素实现了Comparaeble接口 重写了compareTo方法
如果元素不重写接口中的方法。那么存储元素时就会报错
存元素的时候,根据compareTo方法的返回值来决定
返回0:就不存
返回正数:往树的根节点的右边存
返回负数:往树的根节点的左边存


[Java] 纯文本查看 复制代码
string和Integer默认实现了Compareble和重写了compareTo方法  
 TreeSet<String> tree = new TreeSet<>();  
        tree.add("b");  
        tree.add("a");  
        tree.add("b");  
        tree.add("c");  
        tree.add("d");  
        tree.add("a");  
        System.out.println(tree); 


2。比较器排序 有参构造采用的就是比较器排序
  创建TreeSet对象的时候,传进来一个比较器的子类对象
  接口 Comparator<T> 比较器

  int compare(T o1, T o2) 比较方法比较用来排序的两个参数
  根据子类对象重写比较器中的compare方法,根据方法返回值的正负和0来排序元素和去重
  对于自定义类,采用匿名内部类的方法去重写方法传参数比较方便,当然自己定义一个子类也是可以的

[Java] 纯文本查看 复制代码
TreeSet t = new TreeSet<>(new Comparator<Integer>() {  
            @Override  
            public int compare(Integer s1, Integer s2) {  
                return s1 - s2;  
            }  
        });  
        t.add(6);  
        t.add(6);  
        t.add(3);  
        t.add(2);  
        t.add(1);  
        t.add(4);  
        t.add(5);  
        t.add(4);  
        t.add(3);  
        System.out.println(t);  
    }//[1,2,3,4,5,6] 

LinkedHashSet(有序,唯一)LinkedhashSet  底层数据结构是链表和哈希表
元素有序靠链表保证,元素唯一靠哈希表保证
[Java] 纯文本查看 复制代码
LinkedHashSet<Integer> list = new LinkedHashSet<>();  
        list.add(Integer.valueOf(1));  
        list.add(1);  
        list.add(2);  
        list.add(3);  
        list.add(4);  
        list.add(5);  
        System.out.println(list);//[1, 2, 3, 4, 5] 

用自然排序:采用自然排序 要求元素必须实现Comparable接口
          然后重写compareTo方法 根据自己的排序方式 返回正负或0



用比较器去排序:采用匿名内部类的方式去传入比较器 的子类对象,重写compare方法

接口 Map<K,V>将键映射到值的对象,一个映射不能包含重复的键,每个键最多映射一个值,K为键。V为值。map集合中,一个键只对应一个值,当键相同时值会覆盖,其中允许使用null键与null值,map集合的数据结构只和键有关,与值无关常用方法HashMap<String, String> hm = new HashMap<>(); String put = hm.put("老大", "呵呵");//添加元素
String put2 = hm.put("张三", "哈哈");//键相同,值覆盖
String put3 = hm.put("张三", "呵呵");//输出结果:张三呵呵
hm.remove("老大");//移除一个键值对hm.clear();//清空一个集合boolean b = hm.containsKey("张三");//判断一个集合是否包含指定键
boolean v = hm.containsValue("哈哈");//判断一个集合是否包含指定值
boolean empty = hm.isEmpty();//判断一个集合是否为空
类 HashMap<K,V>允许插入null键和null值HashMap和Hashtable的区别:
  HashMap: 非同步,线程不安全,效率高.允许null值和null键
  Hashtable: 同步,线程安全 , 效率低.不允许null值和null键


获取所有值的集合
[Java] 纯文本查看 复制代码
    Collection<String> values = hm.values();  
           for(String v:values){  
               System.out.println(v);  
           }  

获取集合长度hm.size();


遍历集合有两种方法1。通过键来找值
[Java] 纯文本查看 复制代码
Set<Integer> keys = hm.keySet();//获取所有键的集合  
       for (Integer key : keys) {  
           String value = hm.get(key);//通过键,获取值  
           System.out.println(key + "====" + value);  
       }

2。直接获取   键值对  对象 ,用对象里面的方法获取键跟值
[Java] 纯文本查看 复制代码
Set<Map.Entry<Integer, String>> entries = hm.entrySet();  
       for (Map.Entry<Integer, String> en : entries) {  
           System.out.println(en.getKey() + "===" + en.getValue());  
       }

类 LinkedHashMap<K,V>底层数据结构是链表和哈希表,元素有序且唯一其特点是保存了记录的插入顺序,先得到的记录先插入,LinkedHashMap取的顺序就是自己存的顺序

类 TreeMap<K,V>
TreeMap集合不允许插入null键,可以插入null值TreeMap集合的两种排序方法:自然排序和比较器排序方法与TreeMap大致相同


案例演示:斗地主,经常拿来看看,复习一下
使用ArrayList
[Java] 纯文本查看 复制代码
    package org.westos.demo4;  
      
    import java.util.ArrayList;  
    import java.util.Collections;  
      
    public class MyTest7 {  
        public static void main(String[] args) {  
            //模拟斗地主的发牌和看牌  
            // 模拟斗地主洗牌和发牌,牌没有排序  
            //1.定义一个牌盒 来装牌  
            //2.生成54张牌装进牌盒  
            //3.洗牌  
            //4.发牌  
            //5.看牌  
            //1.创建牌盒子  
            ArrayList<String> pokerBox = new ArrayList<>();  
            //2.生成牌 ,装进牌盒  
            String[] colors = {"♣", "♠", "♥", "◆"};  
            String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};  
            for (String color : colors) {  
                for (String num : nums) {  
                    String pai = color.concat(num);  
                    pokerBox.add(pai);  
      
                }  
      
            }  
            //添加大小王  
            pokerBox.add("★");  
            pokerBox.add("☆");  
      
            //洗牌  
            Collections.shuffle(pokerBox);  
            Collections.shuffle(pokerBox);  
            Collections.shuffle(pokerBox);  
      
            //  System.out.println(pokerBox);  
            // 发牌  
            ArrayList<String> 底牌 = new ArrayList<>();  
            ArrayList<String> 周星驰 = new ArrayList<>();  
            ArrayList<String> 吴宗宪 = new ArrayList<>();  
            ArrayList<String> 曾志伟 = new ArrayList<>();  
            //发牌的算法  
    //        周星驰 0 3 6 9  
    ////        吴宗宪 1 4 7 10  
    ////        曾志伟 2 5 8 11  
            for (int i = 0; i < pokerBox.size(); i++) {  
                //留底牌  
                if (i >=pokerBox.size() - 3) {  
                    底牌.add(pokerBox.get(i));  
                } else if (i % 3 == 0) {  
                    周星驰.add(pokerBox.get(i));  
      
                } else if (i % 3 == 1) {  
                    吴宗宪.add(pokerBox.get(i));  
      
                } else if (i % 3 == 2) {  
                    曾志伟.add(pokerBox.get(i));  
                }  
            }  
      
            //看牌  
            lookPoker("周星驰",周星驰);  
            lookPoker("吴宗宪",吴宗宪);  
            lookPoker("曾志伟",曾志伟);  
            lookPoker("底牌",底牌);  
        }  
      
        private static void lookPoker(String name, ArrayList<String> list) {  
            System.out.println(name);  
            for(String s:list){  
                System.out.print(s+"  ");  
            }  
            System.out.println();  
        }  
    }  

使用HashMap
[Java] 纯文本查看 复制代码
    package org.westos.demo4;  
      
    import sun.security.action.PutAllAction;  
      
    import java.util.*;  
      
    public class MyTest8 {  
        public static void main(String[] args) {  
            //创建牌盒  
            HashMap<Integer, String> pokerBox = new HashMap<>();  
            //生成牌,往牌盒里面装牌  
            String[] colors = {"♣", "♠", "♥", "◆"};  
            String[] nums = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};  
            int index = 0;//定义索引  
            for (String num : nums) {  
                for (String color : colors) {  
                    String poker = num.concat(color);  
                    pokerBox.put(index, poker);  
                    index++;  
      
                }  
            }  
            //手动添加两张王  
            pokerBox.put(index, "★");  
            index++;  
            pokerBox.put(index, "☆");  
            //System.out.println(pokerBox);  
            //洗牌  
            Set<Integer> integers = pokerBox.keySet();  
            ArrayList<Integer> suoyin = new ArrayList<>();  
            for (Integer i : integers) {  
                suoyin.add(i);  
      
            }  
      
            // System.out.println(suoyin);  
            Collections.shuffle(suoyin);  
            Collections.shuffle(suoyin);  
            Collections.shuffle(suoyin);  
      
            //发牌  
            TreeSet<Integer> 底牌 = new TreeSet<Integer>();  
            TreeSet<Integer> 周星驰 = new TreeSet<Integer>();  
            TreeSet<Integer> 吴宗宪 = new TreeSet<Integer>();  
            TreeSet<Integer> 曾志伟 = new TreeSet<Integer>();  
            for (int i = 0; i < suoyin.size(); i++) {  
                if (i >= suoyin.size() - 3) {  
      
                    底牌.add(suoyin.get(i));  
                } else if (i % 3 == 0) {  
      
                    周星驰.add(suoyin.get(i));  
                } else if (i % 3 == 1) {  
      
                    吴宗宪.add(suoyin.get(i));  
                } else if (i % 3 == 2) {  
                    曾志伟.add(suoyin.get(i));  
                }  
      
            }  
      
            //看牌  
            lookPoker("底牌", 底牌, pokerBox);  
            lookPoker("周星驰", 周星驰, pokerBox);  
            lookPoker("吴宗宪", 吴宗宪, pokerBox);  
            lookPoker("曾志伟", 曾志伟, pokerBox);  
      
      
        }  
      
        private static void lookPoker(String name, TreeSet<Integer> ts, HashMap<Integer, String> pokerBox) {  
            System.out.println(name);  
            for (Integer in : ts) {  
                System.out.print(pokerBox.get(in));  
            }  
      
            System.out.println();  
      
        }  
    }  







评分

参与人数 1黑马币 +5 收起 理由
KC2017 + 5 赞一个!

查看全部评分

1 个回复

倒序浏览
Hello, World!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马