Java SE-核心-集合类二

List接口
/**
 *   list接口继承了Collection接口,可在Collection基础之上添加一些新方法
 * */
public class Demo01List {
    public static void main(String[] args) {
        //使用多态创建集合对象
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        //遍历集合
        System.out.println(list);
        System.out.println("----------");

        //在指定索引位置添加元素
        list.add(1, "马龙");
        System.out.println(list);
        System.out.println("----------");

        //更改指定索引位置元素
        String setStr = list.set(0, "刘国梁");
        System.out.println(list);
        System.out.println("----------");

        //移出指定索引位置元素
        String removeEle = list.remove(3);
        System.out.println(list);
        System.out.println("----------");

        //list集合带有索引
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

ArrayList类
  • ArrayList接口继承了List集合常用的方法
  • 优点:因为底层时数组,所以查询效率较高
  • 缺点:每次添加一个元素,都是通过调用System.arraycopy()方法复制一个数组,将新元素添加进去
  • ‘注意:此实现不是同步的,即多线程
LinkedList类
  • LinkedList 集合同样也是继承了List集合
  • 优点:因为底层使用链表实现,所以增删效率较高
  • 缺点:查询效率低
  • 注意:此实现不是同步的,即多线程
/**
 *   LinkedList 集合同样也是继承了List集合
 *     优点:因为底层使用链表实现,所以增删效率较高
 *     缺点:查询效率低
 *   注意:此实现不是同步的,即多线程
 *  * */
public class Demo01LinkedList {
    public static void main(String[] args) {
        //创建一个LinkedList集合
        LinkedList<String> linked = new LinkedList<>();
        linked.add("a");
        linked.add("b");
        linked.add("c");
        linked.add("d");
        System.out.println(linked);
        System.out.println("-------------------");

        //向集合头添加元素
        linked.push("头部元素");
        linked.addFirst("头部元素2");
        System.out.println(linked);
        System.out.println("-------------------");

        //向集合尾部添加元素
        linked.addLast("尾部元素1");
        System.out.println(linked);
        System.out.println("--------------------");

        //获取头部元素
        String firstEle = linked.getFirst();
        System.out.println(firstEle);
        System.out.println("                    ");

        //获取尾部元素
        String lastEle = linked.getLast();
        System.out.println(lastEle);
        System.out.println("-------------------");

        //删除并返回头部元素
        String removeEle = linked.removeFirst();
        String pop = linked.pop();

        //删除并返回尾部元素
        String removeElel = linked.removeLast();

        System.out.println(linked);
    }
}
Vector类
  • Vector集合继承了List接口
  • 优点:Vector集合底层时数组
  • 注意:Vector集合是同步的,即单线程
Set接口
  • Set接口继承了Collection接口
  • 注意:Set中集合没有索引,和Collection接口中方法相同
  • Set集合中不存储重复值元素
HashSet接口
  • HashSet接口继承了Set接口
  • 不允许存储重复元素
  • 无索引
  • 是一个无序的集合
  • 底层是一个哈希表结构,查询效率高
  • 注意:HashSet中集合不保证顺序的持久性
  • 底层不是同步的,即单线程
hashCode()方法
  • 哈希值:是一个十进制的整数,由系统随机给出,是一个对象的逻辑地址,不是实际的物理地址
  • 在Object类中有一个方法可以获取哈希值
  • public native int hashCode()
  • native代表是本地方法
public class Person extends Object {
    
    //在创建String类对象时才重写此方法
    @Override
    public int hashCode() {
        return 1;
    }
}

/**
 *    哈希值:是一个十进制的整数,由系统随机给出,是一个对象的逻辑地址,不是实际的物理地址
 *        在Object类中有一个方法可以获取哈希值
 *          public native int hashCode()
 *             native代表是本地方法
 * */
public class Demo02HashCode {
    public static void main(String[] args) {
        //Person继承了Object类,所以可以使用hashCode()方法
        Person p1 = new Person();
        int h1 = p1.hashCode();
        System.out.println(h1);

        Person p2 = new Person();
        int h2 = p2.hashCode();
        System.out.println(h2);

        /**
         *   toString() 方法源码
         *     return getClass().getName + "@" + Integer.toHexString(hashCode());
         *
         * */
        System.out.println(p1);
        System.out.println(p2);

        /**
         *   重写String类中的hashCode()方法
         *
         * */
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println("重地" + s1.hashCode());
        System.out.println("通话" + s2.hashCode());
    }
}

哈希表
哈希表结构图解
  • 在jdk1.8之前哈希表结构:数组+链表
  • 在jdk1.8之后哈希表结构:数组+红黑树
  • 当链表的节点个数大于8个时会变成红黑树

在这里插入图片描述

Set集合不存储重复元素原理
  • 当调用add()方法向集合中添加元素时,add()方法会调用元素的hashCode()方法和equals()方法;hashCode()方法判断是否有哈希冲突,equals()判断是否有重复元素
  • Set集合存储不重复元素前提:存储的元素必须重写hashCode()方法和equals()方法
  • 注意:八大基本元素的包装类已经重写了hashCode()方法和equals()方法

在这里插入图片描述

HashSet存储自定义元素
  • 存储自定义元素时,若要存储重复元素要重写hashCode()方法和equals()方法
public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = 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;
    }
}

/**
 *    哈希表存储不重复元素
 *         八大基本类型的包装类已经重写了hashCode()方法和equals()方法
 *         这里要自定义类且存储不重复元素要重写hashCode()方法和equals()方法
 *     注意:年龄和姓名相同时看作相同元素
 * */
public class Demo01HashCode {
    public static void main(String[] args) {
        HashSet<Person> set = new HashSet<>();
        //创建对象
        Person p1 = new Person("小王", 18);
        Person p2 = new Person("小王", 18);
        Person p3 = new Person("小张", 19);

        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);  //过没有重写俩个方法则三个对象都可以添加到set集合中
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1.equals(p2));  //false若没有重写此方法比较的时俩个对象的地址值

    }
}

LinkedHashSet集合
  • 底层是一个哈希表+链表,(多了一条链表记录元素的存储顺序)保证元素有序
/**
 *    LinkedHashSet
 *        底层是一个哈希表+链表,(多了一条链表记录元素的存储顺序)保证元素有序
 *  * */
public class Demo01LinkedHashSet {
    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("小王");
        hashSet.add("小王");
        hashSet.add("校长");
        System.out.println(hashSet);  //无序 不存储重复元素

        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("小张");
        linkedHashSet.add("小张");
        linkedHashSet.add("小王");
        System.out.println(linkedHashSet);  //有序 不存储重复元素
    }
}
排序
使用Collections接口中的方法对集合进行排序
  • 注意:被排序的元素必须实现Comparable接口,重写compareTo方法
  • 规定:自己-参数 :升序,否则降序
案例一
public class Person implements Comparable<Person>{
    private String name;
    private int age;

    @Override
    public int compareTo(Person person) {
        return this.getAge() - person.getAge();  //升序
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + 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;
    }
}

public class Demo01Collection {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();


        //第二个参数为可变参数,即可以添加任意个元素
        //向集合中添加元素
        Collections.addAll(list, "小张", "小王", "往");
        System.out.println(list);

        //打乱集合中的顺序
        Collections.shuffle(list);
        System.out.println(list);

        //自定义类元素排序
        Person p1 = new Person("小张", 10);
        Person p2 = new Person("小王", 19);
        Person p3 = new Person("小周", 8);

        ArrayList<Person> list1 = new ArrayList<>();
        list1.add(p1);
        list1.add(p2);
        list1.add(p3);

        //方法一按照年龄升序排序
        Collections.sort(list1, (o1, o2)->o1.getAge() - o2.getAge());  //用此方法在Person类中可以不用实现Comparable接口
        System.out.println(list1);
        /**
         *  方法二:也可在在Person类创建时继承Comparable接口
         *        在其中重写compareTo()方法
         *
         * */
    }
案例二
/**
 *    使用Collections接口中的方法对集合进行排序
 *        注意:被排序的元素必须实现Comparable接口,重写compareTo方法
 *    规定
 *       自己-参数  :升序
 *       否则降序
 * */
public class Demo01Sort {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(1);
        list.add(3);
        list.add(6);
        System.out.println(list);

        //使用sort方法排序,默认升序
        Collections.sort(list);
        System.out.println(list);

        //(方法一)重写compareTo()方法降序排列
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer integer, Integer t1) {
                return t1 - integer;
            }
        });
        //(方法二)使用lambda表达式
        Collections.sort(list, (Integer t1, Integer t2)->t1-t2);
        System.out.println(list);
    }
}

Comparetor和Comparable区别
  • Comparable是集合内部比较,自己(this)和参数作比较,自己需要实现comparable接口,重写compareTo()方法
  • Comparetor在集合外部比较相当于找一个第三方的裁判比较
Map集合
  • Collection集合称为单列集合,Map集合称为双列集合
使用键值对遍历集合图解

在这里插入图片描述

  • 使用键值对遍历map集合
  • 首先使用map集合中的entrySet(0方法获取entry对象且存储在set集合中
  • 遍历set集合,获取每一个entry对象
  • 过entry集合中的getKey()和getValue()方法获取每个entry对象的键值对
  • 1、首先获取键集合set
  • 2、遍历键集合set使用get方法获取值
/**
 *   遍历map集合
 *
 * */
public class Demo02KeySet {
    public static void main(String[] args) {
        show();
    }

    /**
     *   方式一:通过键值对方式
     *     1、首先获取键集合set
     *     2、遍历键集合set使用get方法获取值
     * */
    public static void show() {
        //创建map集合
        Map<String, Integer> map = new HashMap<>();
        map.put("张继科", 180);
        map.put("樊振东", 180);
        map.put("许昕", 189);

        /**
         *  通过键值对遍历集合
         * */
        //获取set集合
        Set<String> set = map.keySet();
        for (String key : set) {
            int value = map.get(key);
            System.out.println(key + "=" + value);
        }
        /**
         *  也可用迭代器遍历集合
         * */
    }
}

使用EntrySet遍历集合
/**
 *    使用键值对遍历map集合
 *       1、首先使用map集合中的entrySet(0方法获取entry对象且存储在set集合中
 *       2、遍历set集合,获取每一个entry对象
 *       3、通过entry集合中的getKey()和getValue()方法获取每个entry对象的键值对
 *  * */
public class Demo03EntrySet {
    public static void main(String[] args) {
        //创建一个map集合(多态)
        Map<String, Integer> map = new HashMap<>();

        map.put("马龙", 175);
        map.put("樊振东", 170);
        map.put("张继科", 180);

        //创建set集合存储entry对象
        Set<Map.Entry<String, Integer>> set = map.entrySet();
        //遍历set集合
        for (Map.Entry<String, Integer> e : set) {
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key + "=" + value);
        }
    }
}
HashMap集合
  • hashMap底层实现是哈希表
  • jdk1.8之前:数组+单向链表
  • jdk1.8之后:数组+单向链表/红黑树(当链表节点个数大于8个时为红黑树)
  • 是一个无序的集合
/**
 *    HashMap集合常用一些方法
 *         hashMap底层实现是哈希表
 *            jdk1.8之前:数组+单向链表
 *            jdk1.8之后:数组+单向链表/红黑树(当链表节点个数大于8个时为红黑树)
 *            是一个无序的集合
 *    LinkedHashMao集合:
 *         底层实现是:哈希表+单向链表(巴奥赵正得迭代的顺序)
 *         是一个有序的集合
 * */
public class Demo01HashMap {
    public static void main(String[] args) {
        //创建一个map集合(多态)
        Map<String, Integer> map = new HashMap<>();
        /**
         *   添加元素
         * */
        map.put("马龙", 175);
        map.put("樊振东", 170);
        map.put("张继科", 180);
        System.out.println(map);
        Integer hight = map.put("马龙", 178);  //这里接收相同的键被替代的值,若键在map集合中未出现,则返回null
        System.out.println(map);
        /**
         *  删除键值对
         * */
        Integer h = map.remove("樊振东");
        System.out.println(map);

        /**
         *  获取键对应的值
         * */
        Integer h2 = map.get("张继科");  //这里要用包装类型变量接收,因为当键不存在时返回null
        System.out.println(h2);

        /**
         *  判断集合是否包含键 或值
         * */
        boolean flag = map.containsKey("马龙");
        boolean flag2 = map.containsValue("180");
        System.out.println(flag);
        System.out.println(flag2);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值