2022-08-06 第八组 卢睿 学习心得

集合

今日重点

  1. Collection接口
  2. List
  3. ArrayList
  4. LinkedList
  5. Vector
  6. Set
  7. Map
  8. 集合的遍历
  9. 迭代器
  10. 其他的集合
  11. 面试题

List

数据是有顺序(添加的先后顺序)的,数据是可以重复。
ArrayList:内部结构是数组。比较适合做高频率的查找,遍历。
LinkedList:双向链表。比较适合做高频率的新增和删除。
Vector:和ArrayList几乎一模一样。

面试题:

  1. Collection和Map接口的区别
  2. ArrayList和LinkedList的区别
  3. ArrayList和Vector的区别
public class Ch01 {
    public static void main(String[] args) {
//        List<String> list = new LinkedList<>();
        LinkedList<String> list = new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        // 我们在创建对象的时候用的是多态
        // 父类对象---子类引用
        // 我们创建出来的对象只能够调用父类和子类中都有的方法
        list.addFirst("z");
        list.addLast("x");

        list.removeFirst();
        list.removeLast();

        // 根据下标索引获取指定位置的元素
        System.out.println(list.get(2));

        System.out.println(list);
    }
}

Collection接口:

List:有顺序,元素可以重复,顺序指的是添加的先后顺序
Set:没有顺序,元素不可以重复,顺序指的是添加的先后顺序

Set其实是有顺序,内部有一个专门排序的算法。

  1. 所谓的无序不等于随机
  2. 所谓的无序指的是没有按照添加的先后顺序,其实内部是做了排序的。

面试题:

  1. List和Set的区别
  2. HashSet和LinkedHashSet的区别和联系
public class Ch02 {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(Integer.valueOf(200));
        set.add(4);
        set.add(15);
        set.add(38);
        set.add(Integer.valueOf(200));
        System.out.println(set);
    }
}

Set集合如何确保数据的不重复?

保证数据类型的类要重写hashCode和equals方法。

public class Ch03 {

    public static void main(String[] args) {
        Set<Person> set = new HashSet<>();
        set.add(new Person("张三",1001));
        set.add(new Person("张三",1001));
        set.add(new Person("张三",1001));
        set.add(new Person("张三",1001));

        // 引用数据类型
        // set集合所谓的不能重复,默认情况下比较地址
        System.out.println(set);
    }
}

TreeSet

排序规则:
要排序的对象的类必须实现Comparable接口

public class Ch04 {

    public static void main(String[] args) {
//        Set<Integer> tree = new TreeSet<>();
//        tree.add(-100);
//        tree.add(100);
//        tree.add(10);
//        tree.add(50);
//        Set<String> tree = new TreeSet<>();
//        tree.add("1");
//        tree.add("a");
//        tree.add("哈哈哈哈哈哈");
//        tree.add("%");

        Set<Person> tree = new TreeSet<>();
        tree.add(new Person("张岳",1001));
        tree.add(new Person("李四",1010));
        tree.add(new Person("费四",1003));

        System.out.println(tree);
    }
}

LinkedHashSet

在添加数据的同时维护数据的添加顺序,效率要比HashSet略低一些。

public class Ch05 {

    public static void main(String[] args) {
        LinkedHashSet<String> set = new LinkedHashSet<>();
        set.add("1");
        set.add("a");
        set.add("哈哈哈哈哈哈");
        set.add("%");

        System.out.println(set);
    }
}

比较接口

Comparable接口:自然排序,排序规则是固定。
Comparator接口:临时排序

public class Ch06 {

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>(16);
        list.add(new Person("张岳",1100));
        list.add(new Person("李四",1010));
        list.add(new Person("刘海柱",1020));

//        list.sort(new Comparator<Person>() {
//            @Override
//            public int compare(Person o1, Person o2) {
//                return 0;
//            }
//        });
        list.sort((o1,o2) -> {
            if(o1.getId() < o2.getId()){
                return -1;
            }
            if(o1.getId().equals(o2.getId())){
                return 0;
            }
            return 1;
        });
        System.out.println(list);
    }
}

Map接口:

  1. 存储对值K-V key-value
  2. key不能重复,value是可以重复的
  3. 没有顺序(添加的先后顺序)

HashMap内部存储结构

jdk1.7之前:链表 + 数组
jdk1.7及之后:链表 + 数组 + 红黑树

HashMap基本上面试90%问原理!!!

public class Ch07 {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("1001","张岳");
        map.put("1002","赵红兵");
        map.put("1003","小北京");
        map.put("1004","李四");
        map.put("1004","张浩然");
        map.put("1005","张浩然");

        System.out.println(map);
        System.out.println(map.get("1003"));
        System.out.println(map.values());
        System.out.println(map.keySet());

    }
}

Hashtable和HashMap几乎一模一样

面试题:

Hashtable和HashMap的区别
1.HashMap是线程异步,线程不安全的,Hashtable是线程同步,线程安全
2.HashMap的key是可以为null的,Hashtable是不可以为null

public class Ch08 {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put(null,null);
        System.out.println(map);

        Hashtable<String, String> table = new Hashtable<>();
        table.put(null,null);

        System.out.println(table);
    }
}

Properties:属性

Properties是Hashtable的子类,更多地是用来操作属性文件。

List集合的遍历

public class Ch10 {

    public static void main(String[] args) {
       List<String> list = new ArrayList<>();
       list.add("a");
       list.add("b");
       list.add("c");
       list.add("d");

       // 1.for循环
//        for (int i = 0; i < list.size(); i++) {
//            System.out.println(list.get(i));
//        }
        // 2.foreach语句
//        for (String s : list) {
//            System.out.println(s);
//        }
        // 3.迭代器
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()) {
            String s = iterator.next();
            iterator.remove();
//            System.out.println(s);
        }
        System.out.println(list);
    }
}

遍历

public class Ch11 {

    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(4);
        set.add(15);
        set.add(38);

        // 2.迭代器
        Iterator<Integer> iterator = set.iterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // 1.增强for
//        for (Integer integer : set) {
//            System.out.println(integer);
//        }

//        for (int i = 0; i < set.size(); i++) {
//
//        }
    }
}

迭代器

import java.util.*;

public class Ch12 {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("1001","张岳");
        map.put("1002","赵红兵");
        map.put("1003","小北京");
        map.put("1004","李四");
        map.put("1005","张浩然");

        // 4.迭代器
        Set<String> strings = map.keySet();
        Iterator<String> iterator = strings.iterator();
        while(iterator.hasNext()) {
            String s = iterator.next();
            System.out.println(s + "->" + map.get(s));
        }

        // 3.增强for循环
        // Entry是hashmap的一个内部类
        // 每一组键值对就是一个Entry对象
//        Set<Map.Entry<String, String>> entries = map.entrySet();
//        for (Map.Entry<String, String> entry : entries) {
//            System.out.print(entry.getKey() + "->");
//            System.out.println(entry.getValue());
//        }

        // 2.增强for循环
//        Set<String> strings = map.keySet();
//        Collection<String> values = map.values();

        // 1.for循环
//        Set<String> strings = map.keySet();
//        for (String s : strings) {
//            System.out.println(s + "->" + map.get(s));
//        }
    }
}

迭代中删除元素

public class Ch13 {

    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("tom");
        names.add("lucy");
        names.add("lucy");
        names.add("lucy");
        names.add("jerry");

//        for (int i = 0; i < names.size(); i++) {
//            if(Objects.equals(names.get(i),"lucy")){
//                names.remove(i);
//                // 1.回调指针
//                i--;
//            }
////            if("lucy".equals(names.get(i))){
////
////            }
//        }
        // 2.逆序遍历
//        for (int i = names.size() - 1; i >= 0; i--) {
//            if(Objects.equals(names.get(i),"lucy")){
//                names.remove(i);
//            }
//        }
        // 3.使用迭代器(推荐)万无一失
        Iterator<String> iterator = names.iterator();
        while(iterator.hasNext()) {
            String s = iterator.next();
            if(Objects.equals(s,"lucy")){
                iterator.remove();
            }
        }
        // 4.增强for循环
//        for (String s : names) {
//            if(Objects.equals(s,"lucy")){
//                names.remove(names.indexOf(s));
//            }
//        }
        System.out.println(names);
    }
}

其他的集合

  1. LinkedHashMap,在HashMap的基础上维护了一个双向链表。
  2. TreeMap:天然支持排序
  3. Collections:Collections是一个工具类

面试题

线程安全问题:

迭代器是依赖于集合而存在,在判断成功以后,集合中新增了元素,
迭代器不知道,所以就报错。

解决
  1. 迭代器遍历元素,迭代器删除元素
  2. 普通for循环遍历,集合删除
public class Ch15 {

    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("tom");
        names.add("lucy");
        names.add("lucy");
        names.add("lucy");
        names.add("jerry");

        for (String s : names) {
            if(Objects.equals(s,"lucy")){
//                names.remove(s);
                names.add(s);
            }
        }

    }
}

案例中的Person类

public class Person implements Comparable<Person> {

    private String name;
    private Integer id;

    public Person(String name, Integer id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (!name.equals(person.name)) return false;
        return id.equals(person.id);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + id.hashCode();
        return result;
    }

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

    /*
        返回值代表什么?
        int
        代表排序结果
        负数-1:比较的两个值调用者小
        0:两个值相等
        正数1:比较的两个值调用者大
     */
    @Override
    public int compareTo(Person p) {
        if(this.id > p.id){
            return -1;
        }
        if(this.id.equals(p.id)){
            return 0;
        }

        return 1;
    }
}

总结

集合需要掌握的:
1.如何创建需要的集合。多态
2.主要用到的是List和Map
3.各种区别?
4.各种集合API的调用
5.两个比较接口
6.各种集合的特点,从接口层面,到实现类层面
7.重点集合的内部结构。ArrayList,HashSet,HashMap
8.各种集合的遍历
9.并发问题

最重要的集合:
ArrayList、HashMap

posted @ 2022-08-06 22:04  LegendR  阅读(47)  评论(0)    收藏  举报