Java的集合相关知识

集合

引入集合

当我们需要将一些相同结构的个体整合在一起时,就可以考虑使用集合了。比如:新闻列表,购物车等。

集合和数组的对比

  • 集合和数组的相似点

    • 都可以存储多个对象,对外作为一个整体存在
  • 数组的缺点

    • 长度必须在初始化的时候指定,且固定不变
    • 数组采用连续存储空间。删除和添加效率低下
    • 数组无法直接保存映射关系
    • 数组缺乏封装,操作繁琐

集合框架

  • Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中,存放在集合中的数据,被称为元素(element)。

  • 集合框架
    • Collection接口存储一组不唯一,无序的对象
    • List接口存储一组不唯一,有序(索引顺序)的对象
    • Set接口存储一组唯一,无序的对象
    • Map接口存储一组键值对象,提供key到value的映射
      • Key唯一 无序
      • value 不唯一 无序

泛型

​ 泛型是(Generics)JDK1.5 的一个新特性,通常用来和集合对象一起使用,它是程序的增强器,它是目前主流的开发方式。

package com.cnblogs;

import java.util.*;

/*
本类用于测试泛型的优点1
 */
public class TestGeneric1 {
    public static void main(String[] args) {
        /*
        泛型的出现,是想要模拟数组数据类型检查的功能
        数组的好处:在编译时期就检查数据的类型,只要不是规定的类型,就会在编译器中报错,不需要运行程序就可以看到
         */
        String[] arr = new String[5];

        /*
        泛型通常与集合一起使用
         */
        List list = new ArrayList();//需要导包
        list.add("柒");
        list.add(1);
        list.add(1.5);

        /*
        引入泛型,主要是想通过泛型来约束集合中元素的类型<?>
        泛型的好处,可以把报错的时机提前,在编译期就报错,而不是运行以后才抛出异常,在向集合添加元素时
        会先检查元素的类型,不是要求的类型就编译失败
         */
        List<String> list2 = new ArrayList<String>();
        list2.add("柒");
//        list2.add(1);     报错

        /*
        <type> type的值需要查看要存放的类型是什么,根据业务类型自定义,
        但type必须是引用类型,不可能是基本类型
         */
        List<Integer> list3 = new ArrayList<Integer>();
//        List<Integer> list3 = new ArrayList<>();  可以
//        List<Integer> list3 = new ArrayList();    可以
        list3.add(100);
        list3.add(101);
        list3.add(102);
        System.out.println(list3);//[100, 101, 102]
    }
}

package com.cnblogs;
/*
本类用于测试泛型的优点2
 */
public class TestGeneric2 {
    public static void main(String[] args) {
        //需求:分别打印3个数组中的所有元素
        Integer[] a = {1,2,3,4,5,6,7};
        print(a);

        String[] b = {"大哥","二哥","三哥","四哥","五哥","六哥","七弟",};
        print(b);

        Double[] c = {6.0,6.6,6.66,6.666,6.6666,6.66666,6.666666};
        print(c);
    }
    /*
    泛型方法:
        可以写出更加通用的方法,E表示Element元素
        语法:必须两处同时出现:一个是方法参数类型是泛型
        另一个是返回值类型前的泛型,两处一起表示这是一个泛型方法
    */
    private static <E> void print(E[] a) {
        //我们可以通过for循环遍历输出数组的每一个元素
        for(E x : a){
            System.out.println(x);
        }
    }
    
//    private static void print(Integer[] a) {
//        //我们可以通过for循环遍历输出数组的每一个元素
//        for(Integer x : a){
//            System.out.println(x);
//        }
//    }
//    /*
//    增强for循环:只需要对数据从头到尾的遍历一次时使用
//    好处:比普通for循环的语法简单,效率高
//    缺点:无法按照下标来操作元素,只能从头到尾遍历
//    语法:for(2 3 : 1){循环体}
//    1.你需要遍历的数据
//    2.遍历得到的具体元素类型
//    3.遍历得到元素的名字
//     */
//    private static void print(String[] b) {
//        for (String x: b) {
//            System.out.println(x);
//        }
//    }
//    private static void print(Double[] c) {
//        for (Double x: c) {
//            System.out.println(x);
//        }
//    }
    
}

Collection

package com.cnblogs;

import java.util.*;

/*
本类用于测试Collection接口
 */
public class TestCollection {
    public static void main(String[] args) {
        /*
        <Integer>是泛型,用来约束集合中的数据类型,不能是基本类型,必须为引用类型
         */
        Collection<Integer> c = new ArrayList<>();
        //添加元素
        c.add(100);
        c.add(200);
        c.add(300);
        c.add(400);
        c.add(500);
        c.add(600);
        c.add(700);
//        c.clear();    //清空当前集合
        //获取哈希码
        System.out.println(c.hashCode());
        System.out.println(c.toString());//打印集合的具体元素    重写了
        System.out.println(c.equals(200));//false
        System.out.println(c.contains(200));//true  c中是否含有指定元素200
        System.out.println(c.isEmpty());//判断集合是否为空  false
        System.out.println(c.remove(100));//移除集合中的指定元素,成功返回true
        System.out.println(c.size());//6    返回集合的元素个数
        Object[] arr = c.toArray();//将指定的集合转为数组
        System.out.println(Arrays.toString(arr));//[200, 300, 400, 500, 600, 700]

        Collection<Integer> c2 = new ArrayList<>();
        c2.add(2);
        c2.add(4);
        c2.add(6);
        System.out.println(c2);
        c.addAll(c2);//c2集合追加到c的末尾,c2本身不变
        System.out.println(c);
        System.out.println(c2);
        System.out.println(c.containsAll(c2));//true    当前集合是否包含指定集合中的所有元素

        System.out.println(c);//[200, 300, 400, 500, 600, 700, 2, 4, 6]
        System.out.println(c.removeAll(c2));//true  删除c中c2的所有元素
        System.out.println(c);//[200, 300, 400, 500, 600, 700]
        System.out.println(c2);//[2, 4, 6]

        c.add(6);
        System.out.println(c.retainAll(c2));//true     去除除了c2中的所有内容(交集)
        System.out.println(c);//[6]

        /*
        迭代集合/遍历集合:
        1.获取集合的迭代器  c.iterator();
        2.判断集合中是否有下一个可迭代元素  it.hasNext();
        3.获取当前迭代到的元素    it.next();
         */
        Iterator<Integer> it = c.iterator();

        while (it.hasNext()){
            Integer num = it.next();
            System.out.println(num);//6
        }
    }
}

List

package com.cnblogs;

import java.util.*;

/*
本类用于测试list接口
 */
public class TestList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("大娃");
        list.add("二娃");
        list.add("三娃");
        list.add("四娃");
        list.add("五娃");
        list.add("六娃");
        list.add("柒娃");
        System.out.println(list);

        //测试继承自Collection的方法
//        list.clear();清空集合
//        System.out.println(list.contains("张三"));//false
//        System.out.println(list.equals("大娃"));//false
//        System.out.println(list.isEmpty());//false
//        System.out.println(list.remove("三娃"));
//        System.out.println(list.size());//7

        //测试List自己的方法
        list.add("张三");//追加在最后
        list.add(1,"李四");//索引从0开始
        list.add(3,"张三");
        System.out.println(list);
        System.out.println(list.indexOf("张三"));//第一次出现的索引   3
        System.out.println(list.lastIndexOf("张三"));//最后一次出现的索引      9

        System.out.println(list);
        System.out.println(list.remove(5));//四娃     删除指定元素并返回
        System.out.println(list.get(3));//张三
        System.out.println(list);
        list.set(8,"王二麻子");
        System.out.println(list);

        //测试集合间的操作
        List<String> list2 = new ArrayList<>();
        list2.add("1");
        list2.add("2");
        list2.add("3");
        list2.add("4");
        list2.add("5");
        list2.add("6");
        System.out.println(list2);
//        System.out.println(list.addAll(list2));//true
//        System.out.println(list);//[大娃, 李四, 二娃, 张三, 三娃, 五娃, 六娃, 柒娃, 王二麻子, 1, 2, 3, 4, 5, 6]
        list.addAll(1,list2);
        System.out.println(list);//[大娃, 1, 2, 3, 4, 5, 6, 李四, 二娃, 张三, 三娃, 五娃, 六娃, 柒娃, 王二麻子]
        System.out.println(list.containsAll(list2));//true
        System.out.println(list.removeAll(list2));//移除list中list2的所有元素
        System.out.println(list);//[大娃, 李四, 二娃, 张三, 三娃, 五娃, 六娃, 柒娃, 王二麻子]
    }

}

package com.cnblogs;

import java.util.*;

/*
本类用于测试List的接口2
 */
public class TestList2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王二麻子");
        list.add("路人甲");
        list.add("宋兵乙");
        list.add("炮灰丙");
        list.add("土匪丁");

        //迭代集合
        //方法一
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i));
        }
        System.out.println();
        //方法二
        for (String x : list){
            System.out.print(x);
        }
        System.out.println();
        //方法三
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String str = it.next();
            System.out.print(str);
        }
        System.out.println();
        //方法四
        /*
        listIterator 是List特有的迭代器
        Iterator<E> -- 父接口  hasNext()  next()
        listIterator<E> -- 子接口  有自己的特有功能,逆序遍历,添加元素等,不常用
        public interface ListIterator<E>extends Iterator<E>
         */
        ListIterator<String> it2 = list.listIterator();
        while(it2.hasNext()){
            System.out.print(it2.next());
        }
    }
}

ArrayList

package com.cnblogs;

import java.util.*;

/*
本类用于ArrayList相关测试
 */
public class TestArrayList {
    public static void main(String[] args) {
        /*
        底层会自动帮我们创建数组来存放对象,初始长度为10
         */
        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        list.add(400);
        list.add(500);
        list.add(600);
        list.add(700);
        System.out.println(list);
//        list.clear();
//        System.out.println(list);
        System.out.println(list.contains(100));//true
        System.out.println(list.contains("100"));//false
        System.out.println(list.isEmpty());//false
        System.out.println(list.get(0));//100
        System.out.println(list.indexOf(400));//3
        System.out.println(list.lastIndexOf(400));//4
        System.out.println(list.remove(1));//200
        System.out.println(list);//[100, 300, 400, 400, 500, 600, 700]
        System.out.println(list.remove(Integer.valueOf(300)));
        System.out.println(list);//[100, 400, 400, 500, 600, 700]
//        System.out.println(list.remove(300));
        /*
        上面会报错,数组下标越界,如果传入300会认为是int类型的索引,所有,如果想要删除指定元素
        需要手动把300装箱成Integer类型
         */
        System.out.println(list.remove(Integer.valueOf(400)));
        System.out.println(list);//[100, 400, 500, 600, 700]
        System.out.println(list.set(2,888));//500
        System.out.println(list);//[100, 400, 888, 600, 700]

        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i));
        }

        System.out.println();

        for(Integer x : list){
            System.out.print(x);
        }

        System.out.println();

        Iterator<Integer> it = list.iterator();
        while (it.hasNext()){
            System.out.print(it.next());
        }

        System.out.println();

        ListIterator<Integer> it2 = list.listIterator();
        while (it2.hasNext()){
            System.out.print(it2.next());
        }
    }
}

LinkedList

package com.cnblogs;

import java.util.*;

/*
本类用于LinkedList的相关测试
 */
public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("唐玄奘");
        list.add("白龙马");
        System.out.println(list);
        list.addFirst("玉兔精");
        list.addLast("孔雀精");
        System.out.println(list);//[玉兔精, 孙悟空, 猪八戒, 沙和尚, 唐玄奘, 白龙马, 孔雀精]
        System.out.println(list.getFirst());//玉兔精
        System.out.println(list.getLast());//孔雀精
        System.out.println(list.removeFirst());//玉兔精
        System.out.println(list.removeLast());//孔雀精
        System.out.println(list);//[孙悟空, 猪八戒, 沙和尚, 唐玄奘, 白龙马]

        LinkedList<String> list2 = new LinkedList<>();
        list2.add("水浒传");
        list2.add("西游记");
        list2.add("三国演义");
        list2.add("红楼梦");
        System.out.println(list2);//[水浒传, 西游记, 三国演义, 红楼梦]
        System.out.println(list2.element());//水浒传   获取但不移除首元素
        System.out.println(list2);//[水浒传, 西游记, 三国演义, 红楼梦]

        /*
        查询系统
         */
        System.out.println(list2.peek());//水浒传   获取但不移除首元素
        System.out.println(list2.peekFirst());//水浒传   获取但不移除首元素
        System.out.println(list2.peekLast());//红楼梦  获取但不移除尾元素

        /*
        新增
         */
        System.out.println(list2.offer("聊斋"));
        System.out.println(list2);//[水浒传, 西游记, 三国演义, 红楼梦, 聊斋]
        System.out.println(list2.offerFirst("斗罗大陆"));
        System.out.println(list2.offerLast("斗破苍穹"));
        System.out.println(list2);//[斗罗大陆, 水浒传, 西游记, 三国演义, 红楼梦, 聊斋, 斗破苍穹]

        /*
        移除
         */
        System.out.println(list2.poll());//斗罗大陆
        System.out.println(list2);//[水浒传, 西游记, 三国演义, 红楼梦, 聊斋, 斗破苍穹]
        System.out.println(list2.pollFirst());//水浒传
        System.out.println(list2.pollLast());//斗破苍穹
        System.out.println(list2);//[西游记, 三国演义, 红楼梦, 聊斋]
    }
}

Map

package com.cnblogs;

import java.util.*;

/*
本类用于测试map接口
 */
public class TsetMap {
    public static void main(String[] args) {
        /*
        Map中的数据要符合映射规则,一定要同时指定k和v的数据类型
        至于k和v取什么类型取决于具体的业务需求
         */
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"张三");
        map.put(2,"李四");
        map.put(3,"王二麻子");
        map.put(4,"路人甲");
        map.put(996,"宋兵乙");
        map.put(997,"宋兵乙");
        System.out.println(map);//{1=张三, 2=李四, 3=王二麻子, 4=路人甲, 996=宋兵乙, 997=宋兵乙}
        map.put(1,"炮灰丙");
        System.out.println(map);//{1=炮灰丙, 2=李四, 3=王二麻子, 4=路人甲, 996=宋兵乙, 997=宋兵乙}
        /*
        map中存放着的都是无序数据,map中的value可以重复-比如可以写两个宋兵乙
        map中key不可以重复,重复了后面的value会覆盖前面的value,炮灰丙覆盖了张三
         */

        //方法测试
//        map.clear();//清空集合
        System.out.println(map.hashCode());//1013219698
        System.out.println(map.equals("土匪丁"));//false
        System.out.println(map.isEmpty());//false
        System.out.println(map.size());//6

        //判断集合是否包含指定的键
        System.out.println(map.containsKey(996));//true
        System.out.println(map.containsKey(900));//false
        //判断集合是否包含指定的value值
        System.out.println(map.containsValue("张三"));//false
        System.out.println(map.containsValue("炮灰丙"));//true
        //根据key值来获取对应的value值
        System.out.println(map.get(996));//宋兵乙
        //删除此key值对应的键值对 k和v
        System.out.println(map.remove(997));//宋兵乙
        System.out.println(map);//{1=炮灰丙, 2=李四, 3=王二麻子, 4=路人甲, 996=宋兵乙}

        Collection<String> values = map.values();
        System.out.println(values);//[炮灰丙, 李四, 王二麻子, 路人甲, 宋兵乙]

        Set<Integer> integers = map.keySet();
        System.out.println(integers);//[1, 2, 3, 4, 996]

        //map集合的迭代方式
        /*
        方式一:遍历map中的数据,但是map本身没有迭代器,所以需要先转换成set集合
        Set<key>:把map中的所有key值存入到set集合当中--keySet()
         */
        Set<Integer> keySet = map.keySet();
        Iterator<Integer> it = keySet.iterator();
        while(it.hasNext()){
            Integer key = it.next();
            String value = map.get(key);
            System.out.print("{" + key + "=" + value + "}");//{1=炮灰丙}{2=李四}{3=王二麻子}{4=路人甲}{996=宋兵乙}
        }
        System.out.println();
        /*
        方式二:遍历map集合需要先把map集合转成set集合,是把map中的一对键值k和v作为一个Entry<k,v>
        整体放入set,一对K,V就是一个Entry
         */
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        Iterator<Map.Entry<Integer, String>> it2 = entrySet.iterator();
        while (it2.hasNext()){
            Map.Entry<Integer, String> entry = it2.next();
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.print("{" + key + "=" + value + "}");//{1=炮灰丙}{2=李四}{3=王二麻子}{4=路人甲}{996=宋兵乙}
        }
    }
}

package com.cnblogs;

import java.util.*;

/*
本类用于字符串中字符个数的统计案例
 */
public class TestMap2 {
        /*
        用户输入:abcccc
        输出结果{a = 1,b = 1,c = 4}
         */
    public static void main(String[] args) {
        System.out.println("请输入要统计的字符串:");
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        /*
        统计的是每个字母出现的次数,单个字母是char类型  --> Character
        Integer统计的是字母出现的次数,可以重复,不能作为key
         */
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < input.length(); i++) {
            char key = input.charAt(i);
            //统计次数
            Integer value = map.get(key);
            if(value == null){
                map.put(key,1);
            }else{
                map.put(key,value + 1 );
            }
        }
        System.out.println(map);
//        Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
//        Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
//        while (it.hasNext()){
//            Map.Entry<Character, Integer> entry = it.next();
//            Character key = entry.getKey();
//            Integer value = entry.getValue();
//            System.out.print("{" + key + "=" + value + "}");
//        }

        Set<Character> keySet = map.keySet();
        Iterator<Character> it2 = keySet.iterator();
        while(it2.hasNext()){
            Character key = it2.next();
            Integer value = map.get(key);
            System.out.print("{" + key + "=" + value + "}");
        }
        scanner.close();
    }
}

Set

package com.cnblogs;

import java.util.*;

public class TestSet {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("路人甲");
        set.add("宋兵乙");
        set.add("炮灰丙");
        set.add("土匪丁");
        set.add("土匪丁");
        System.out.println(set);//[炮灰丙, 土匪丁, 路人甲, 宋兵乙]  没有顺序,元素不能重复
        set.add(null);//存入null值
        set.add(null);
        set.add("null");//存入字符串null
        System.out.println(set);//[null, 炮灰丙, null, 土匪丁, 路人甲, 宋兵乙]  只能有一个null值

        /*
        自定义对象,如果想要去重,需要重写hashCode()和equals()方法
         */
    }

}

package com.cnblogs;

import java.util.*;

public class TestSet2 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("路人甲");
        set.add("宋兵乙");
        set.add("炮灰丙");
        set.add("土匪丁");
        set.add("土匪丁");
        set.add(null);
        set.add("null");
        System.out.println(set);//[null, 炮灰丙, null, 土匪丁, 路人甲, 宋兵乙]
//        set.clear();
        System.out.println(set.hashCode());//112899594
        System.out.println(set.equals("皮卡丘"));//false
        System.out.println(set.contains("张三"));//false
        System.out.println(set.isEmpty());//false
        System.out.println(set.remove(null));//true
        System.out.println(set.remove("null"));//true
        System.out.println(set);//[炮灰丙, 土匪丁, 路人甲, 宋兵乙]
        System.out.println(set.size());//4
        Object[] arr = set.toArray();
        System.out.println(Arrays.toString(arr));//[炮灰丙, 土匪丁, 路人甲, 宋兵乙]

        //集合间的操作
        Set<String> set2 = new HashSet<>();
        set2.add("张三");
        set2.add("李四");
        set2.add("王二麻子");
        System.out.println(set2);//[李四, 张三, 王二麻子]

        System.out.println(set.equals(set2));//false
        System.out.println(set.addAll(set2));//true
        System.out.println(set);//[李四, 张三, 炮灰丙, 王二麻子, 土匪丁, 路人甲, 宋兵乙]
        System.out.println(set.containsAll(set2));//true
        System.out.println(set.removeAll(set2));//true
        System.out.println(set);//[炮灰丙, 土匪丁, 路人甲, 宋兵乙]
        //retainAll 取交集存入set中
        set.add("张三");
        System.out.println(set.retainAll(set2));//true
        System.out.println(set);//[张三]

        Iterator<String> it = set2.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");//李四 张三 王二麻子
        }
    }
}

posted @ 2021-07-21 10:38  贪玩的阿柒  阅读(74)  评论(0编辑  收藏  举报