Java学习-工具IDEA-黑马视频(第十一天)

增强for循环

实质上是利用了迭代器

        int[] arr = {1, 3, 4, 5, 2};
        for (int i : arr) {
            System.out.println(i);
        }

        String[] arrs = {"JYQ","WST","WYX"};
        for(String s : arrs){
            System.out.println(s);
        }

        List<String> list = new ArrayList<>();
        list.add("JYQ");
        list.add("WST");
        list.add("WYX");
        //实质上是Iterator迭代器,故add时会出现并发修改异常
//        for(String sl : list){
//            if(sl.equals("JYQ")){
//                list.add("WYT");
//            }
//        }

List数据结构

ArrayList:底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,查询慢,增删快

LinkedList

在这里插入图片描述

Set

不包含重复元素,没有带索引的方法,所以不能使用普通for循环遍历

HashSet

HashSet集合底层数据结构是哈希表

        //HashSet对集合的迭代顺序不做任何保证
        Set<String> set = new HashSet<>();
        set.add("WST");
        set.add("JYQ");
        set.add("WYX");
        set.add("WST");
        
        for(String s : set){
            System.out.println(s);
        }

结果:

JYQ
WYX
WST

哈希值:是JDK根据对象的地址或字符串或数字算出来的int类型的数值

在这里插入图片描述

HashSet集合保证元素唯一性源码分析

在这里插入图片描述

HashSet<String> set = new HashSet<>();
set.add("WST");
set.add("JYQ");
set.add("WYX");
set.add("WST");

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}


public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

//hash值和元素的hashCode()方法相关
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        //如果哈希表未初始化,就对其进行初始化
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;

        //根据对象的哈希值计算对象的存储位置,如果该位置没有元素,就存储该元素
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            /*
                存入的元素和以前的元素比较哈希值
                    如果哈希值不同,会继续向下执行把元素添加到集合
                    如果哈希值相同,会调用对象的equals()方法比较
                        如果返回false,会继续向下执行把元素添加到集合
                        如果返回true,说明元素重复,不存储
            */
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

哈希表

在这里插入图片描述

LinkedHashSet

在这里插入图片描述

TreeSet集合

TreeSet():根据其元素的自然顺序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
没有带索引,不能使用普通for循环遍历
在这里插入图片描述

自然排序Comparable的使用

Student类

package com.Set;

public class Student implements Comparable<Student>{
    public String name;
    public int age;

    public Student() {
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(Student o) {
//        return 1;//返回1按升序,返回-1按降序,0表示不添加该元素
        int num = this.age - o.age;
        //年龄相同,按姓名字母顺序来排序
        int num2 = num == 0 ? this.name.compareTo(o.name) : num;
        //字符串可以直接调用comparaTo方法是因为String重写了compareTo方法
        return num2;
    }
}

实现:

        TreeSet<Student> ts = new TreeSet<>();
        Student s1 = new Student("JYQ",23);
        Student s2 = new Student("WST",24);
        Student s3 = new Student("HBB",24);
        Student s4 = new Student("WYX",0);
        Student s5 = new Student("WYX",0);
        ts.add(s1);//添加的应该为Student对象
        //ClassCastException,直接添加会报错,因为未实现comparable接口
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        for (Student s : ts){
            System.out.println(s.getName()+","+s.getAge())  ;

结果:

WYX,0
JYQ,23
HBB,24
WST,24

Comparator比较器

comparator比较器无需去重写类,可直接利用比较器来实现

        /**
         * 想用Comparator比较器理应给TreeSet传入一个实现了Comparator接口的类
         * 故此方法比较麻烦,需要修改类
         * 也可以用简便方法匿名内部类来实现
         */
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getAge() - s2.getAge();//不能直接访问私有成员,可以通过公共方法来实现
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return num2;
            }
        });
        Student s1 = new Student("JYQ", 23);
        Student s2 = new Student("WST", 24);
        Student s3 = new Student("HBB", 24);
        Student s4 = new Student("WYX", 0);
        Student s5 = new Student("WYX", 0);
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        for(Student s : ts){
            System.out.println(s.getName()+","+s.getAge());
        }

不重复随机数

HashSet不会自动排序,根据哈希值来存放
在这里插入图片描述
TreeSet:会自动排序
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值