2022-08-06 第二小组 张明旭 Java学习记录

目录

心情日记

重点归纳

知识点

List

面试题

 Comparable接口

 面试题

引用数据类型

TreeSet

LinkedHashSet

比较接口

Map接口

Hashtable实现类:(唯一一个没有驼峰的类)

面试题

LinkedHashMap

Properties:属性

集合的遍历

Set集合的遍历

Map集合的遍历

并发异常问题:面试题

其他集合

面试题

集合需要掌握的


心情日记

又是代码少,知识点多的半天,半天?是因为上午放假!๑乛v乛๑嘿嘿。总感觉就是为了要考试,所以考试前两天抓紧讲这么多知识点!脑子不太够用了,本来头发就少。。。

重点归纳

集合的各种接口及其特点

面试题

集合的遍历

并发异常问题

知识点

List

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

面试题

1.Collection和Map接口的区别

 Collection<E>:存放单值的最大父接口(泛型接口)
   子接口:
     List<E>(列表)线性表:和数组类似,List可以动态增长,插入和删除元素会使元素移位
     Set<E>也是线性表,检索元素的效率低,删除和插入的效率高,插入和人删除元素不会使元素移位

Map<K,V>:存放一对值的最大父接口(两个泛型的接口)
 Map(映射):用于保存具有映射关素的数据,Map保存着两组数据:key和value
               key和value都可以是任意的引用数据类型,但key不可以重复

List、Set继承于Collection,Map不是

 2.ArrayList和LinkedList的区别

 ArrayList:List接口的实现类,内部结构是一个数组,涉及到移位,下标维护

LinkedList:List接口的实现类,内部结构是一个链表,便于增加,删除元素。

两者都是异步的,线程不安全。


3.ArrayList和Vector的区别,类似于StringBuffer和StringBuilder
     ArrayList是线程异步的,线程不安全
     Vector是线程同步的,线程安全

 //测试一下LinkedList
    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);
    }

 Comparable接口

CompareTo返回值代表什么?
int类型:代表排序结果
负数-1:表明比较两个值调用者小
0:两个值相等
1:比较两个值调用者大

重写compareTo自己可以规定排序规则

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;
    }

List:有顺序,元素可以重复,顺序指的是添加的先后顺序
Set:没有顺序,元素不可以重复,没有顺序指的是没有按添加的先后顺序
      其实是有顺序的,内部有一个专门的排序算法,所谓的无序不等于随机

 三大集合用的最多的是Map

 面试题

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

2.HashSet和LinkedHashSet的区别和联系

LinkedHashSet是HashSet的子类

LinkedHashset、HashSet是根据hashCode值来决定元素的存储位置

但LinkedHashset同时使用链表维护元素的次序,元素是以添加的顺序保存的

LinkedHashset性能要略低于HashSet的性能

    //Set
    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集合所谓的不能重复默认为比地址,地址不能重复

只要涉及引用数据类型,重复、比较等等都为比地址

保证Set集合元素不重复

Set集合如何确保数据的不重复?(地址不相同,数据都相同)

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

    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

可以排序的Set集合,默认为ASCLL码值从小到大排序

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

    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,有输入先后顺序,但也不能get,较率比较低

    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 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不能重复
3.没有顺序(添加的先后顺序)

只能根据key值取value值

HashMap内部存储结构
JDK1.7之前:链表+二叉树
JDK1.7及之后:链表+二叉树+红黑树

HashMap面试必问你原理!!!

不成文规定五年三跳,不要多跳槽,要稳定!!!

  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实现类:(唯一一个没有驼峰的类)

面试题

Hashtable和HashMap区别
Hashtable和HashMap没啥区别,几乎一模一样
1.HashMap是线程异步的,线程不安全的
  Hashtable是线程同步的,线程安全的

HashMap的key可以为null的,
Hashtable的key是不可以为null的

LinkedHashMap

  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:属性

Hashtable的子类,更多的来操作属性文件
用IO流读取属性文件

集合的遍历

List集合的遍历

1.for循环
2.foreach语句
3.迭代器

 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);
    }

Set集合的遍历

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

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

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

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


    }

Map集合的遍历

1.for循环不太行,首先需要拿所有的key在循环
2.增强for循环
3.增强for循环
  Entry是hashmap的一个内部类,每一组键值对就是一个Entry对象
4.迭代器
  先拿所有的key,相当于用Set进行迭代器操作。

    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","张浩然");
        // 1.for循环
//        Set<String> strings = map.keySet();
//        for (String s : strings) {
//            System.out.println(s + "->" + map.get(s));
//        }

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

        // 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());
//        }

        // 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));
        }

    }

并发异常问题:面试题

删除结合元素删除不干净
删除一个元素,集合能自己移位补缺,指针位置自动往下走,遍历时漏一位,可能是需要删除的元素
怎么删除干净?
1.for循环:回调指针:i--
2.逆序遍历从后往前删除
3.使用迭代器(推荐,万无一失)
(增强for循环:foreach循环操作的是镜像元素,只能遍历,不能删除真实元素。不太行)

  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");
        // 1.for循环
//        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();
            }
        }

        System.out.println(names);
    }

其他集合

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

面试题

线程安全的问题
并发修改异常
用普通方法遍历,但是用迭代器的方法删除元素,普通方法还在遍历,不知道新增或者删除了元素,相当于多线程操作,会出现并发修改异常
反之一样
foreach循环底层是迭代器方法,不能用普通方法删除元素
迭代器是依赖于集合存在,判断成功以后,如果是新增或删除了元素,但是迭代器不知道,所以报错了

集合需要掌握的

1.如何创建需要的集合:主要用多态
   主要用List,Map
2.各种区别(面试题)
3.各种集合方法
4.两个比较接口
5.各种集合的特点:从接口的层面到实现类的层面
6.各种集合API的调用
7.重点集合的内部结构。ArrayList、HashSet、HashMap
8.各种集合的遍历
9.并发问题
10.接口、实现类的方法要去看,有个印象

最重要的集合:
ArrayList和HashMap

推荐学习集合顺序:List->Map->Set

 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);
            }
        }

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值