集合学习日记

1 篇文章 0 订阅
1 篇文章 0 订阅

集合学习总结
集合是一个容器,存放多个元素(元素的数据类型是引用类型(object)),容量没有限制

Collection集合

Collection接口:单列集合,存储一个一个的对象

List接口

List接口:可重复,有顺序 ----动态数组 替换原有数组

  1. ArrayList:最常用的实现类 底层: Object[] elementData 线程不安全,但是效率高

  2. linkedList:针对数据的插入和删除 底层:双向链表存储 数据的插入和删除效率高linkedList底层实现原理

  3. Vector:古老的实现类 底层: Object[] elementData 线程安全,但是效率低

  4. 相同点:都是List接口的实现类,存储数据特点相同

相关方法
package com.lcj.集合;

import jdk.swing.interop.SwingInterOpUtils;

import java.lang.reflect.Array;
import java.util.*;

public class list {
    public static void main(String[] args) {
        /*
        集合的创建,基本方法,增强for循环:内部使用了迭代器
         */

        /*List lt = new ArrayList();
        student s = new student("邓憨憨",41);
        student s1 = new student("邓憨憨1",40);
        student s2 = new student("邓憨憨2",42);
        student s3 = new student("邓憨憨3",43);
        lt.add(s);//添加元素
        lt.add(s1);
        lt.add(s2);
        lt.add(s3);
        lt.add(10);//10是Object类型
        Integer i1 = (Integer)lt.get(4);
        if(i1 == 10){
            lt.add(5);
        }
        List lt1 = new ArrayList<>();
        lt1.add(8);
        lt1.add("lcj");
        lt.addAll(lt1);
        lt.remove(5);//移除obj元素
        //lt.retainAll(lt1);//交集
        //lt.removeAll(lt1);//移除集合lt1中的的所有元素---去除交集
        //contains(object o)  判断集合中是否包含o这个对象  底层:equals();
        boolean b = lt.containsAll(lt1);//判断集合是否包含了 传入集合的所有元素
        boolean contains = lt.contains(10);
        boolean contains1 = lt.contains(s1);
        System.out.println(b);
        System.out.println(contains);
        System.out.println(contains1);



        System.out.println(lt.isEmpty());
        //lt.clear();//清空集合
        for(int i = 0;i < lt.size();i++){//获取长度
            System.out.println(lt.get(i));//获取元素
        }
        for(Object obj:lt){
            System.out.println(obj);
        }*/
        /*
        迭代器:
        执行原理:指针下移
         */
        /*List lt = new ArrayList();
        lt.add("a");
        lt.add("b");
        lt.add("c");
        Iterator ie = lt.iterator();//普通迭代器只能用来遍历
        while (ie.hasNext()){//判断是否有元素
            System.out.println(ie.next());
        }
        ListIterator ir =lt.listIterator();//列表迭代器可以遍历,也可以修改集合中的元素
        while (ir.hasNext()){//进行迭代,3个元素
            String s = (String)ir.next();
            if("b".equals(s)){
                ir.add("java");
            }
            System.out.println(s);
        }*/
        //迭代完我增加了一个元素
        /*
        泛型
         */
        /*List<String> l = new ArrayList<String>();
        l.add("aaa");
        l.add("bbbb");
        l.add("sss");
        for (String s : l) {
            System.out.println(s);

        }*/
        /*
        Collection类对集合进行操作
         */
        List<String> l = new ArrayList<String>();
        l.add("aaa");
        l.add("bbbb");
        l.add("sss");
        for (String s : l) {
            System.out.println(s);
        }
        String s1 = Collections.max(l);//最大值
        System.out.println(s1);
        //Collections.sort(l);//排序:升序
        //Collections.reverse(l);//反转
        Collections.shuffle(l);//随机排序
        for (String s : l) {
            System.out.println(s);

        }

    }
    public static void list1(){
        LinkedList ll = new LinkedList<>();

    }
    /**
     * 传入一个类型的数组,对数组进行处理:复制,返回一个相同类型的集合
     */
    public <E> List<E> copyArray(E[] arr){
        ArrayList<E> es = new ArrayList<>();
        for (E e : arr) {
            es.add(e);
        }
        return es;
    }
}

Set接口

Set接口:数据无序:存放数据不是随机的,也不是在底层数组中根据数组的索引进行添加,而是按照数据的Hashcode值进行排序
数据不可重复:根据equals进行判断,不能返回TRUE,保证相同元素只能添加一个

HashSet底层实现

HashSet:无参构造 public HashSet() {
map = new HashMap<>();
}

LinkedHashSet

LinkedHashSet:按照添加的顺序的遍历,使用了双向链表来记录添加顺序 使用场景:频繁遍历

TreeSet

TreeSet:按照对象的指定属性进行排序 添加的元素:相同类的对象
排序方式:比较器
自然排序中比较两个对象是否相同:compareTo()
定制排序

Map集合

Map接口:双列存储,存储key-value对(Entry对象)的数据

HashMap

HashMap:主要的实现类,线程不安全 效率高,不能存储null的KEY和value LinkedHashMap:按照添加的顺序的遍历
原因:在原有HashMap的底层基础上,添加了一对指针,指向后一个元素和前一个元素 使用场景:频繁遍历

TreeMap

TreeMap:按照KEY进行排序

底层实现原理

向map集合添加key-value对对象p:
首次调用put方法才在底层去创建长度为16的数组,获取p的key的Hash值,根据哈希值判断他在数组中的位置
如果该位置上没有其他元素,则将该对象放在数组的这个位置
如果改位置上有元素(通过链表进行存储,红黑树),则比较p的Key的哈希值与各个元素的哈希值
如果不同则说明不是相同元素,添加p
如果相同则调用p的key的equals方法与各个元素的key进行比较,
true:说明是相同元素,不进行添加
false:不同元素,添加

注意

jdk8:1.new HasMap():底层没有创建长度为16的数组
2.底层数组为Node[]
3.首次调用put方法才在底层去创建长度为16的数组
4.红黑树:折半查找
使用的前提条件:底层数组长度>64 数组中某一索引位置上使用链表存储的数据>8

源码关键量

源码关键量:
DEFAULT_INITIAL_CAPACITY 16 HashMap的默认容量
DEFAULT_LOAD_FACTOR 0.75 加载因子 得出数组的临界值,达到临界值进行扩容(既不浪费空间,控制链表结构较少)
TREEIFY_THRESHOLD:链表长度大于8转换成红黑树
MIN_TREEIFY_CAPACITY:桶中得NODE被树化时最小的hash表容量:64
threshold:扩容得临界值 DEFAULT_INITIAL_CAPACITY*DEFAULT_LOAD_FACTOR 12

常用方法

package com.lcj.集合;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class map {
    public static void main(String[] args) {
        Map<Integer,student> m = new HashMap<>();
        student s4 = new student("邓憨憨",41);
        student s1 = new student("邓憨憨1",40);
        student s2 = new student("邓憨憨2",42);
        student s3 = new student("邓憨憨3",43);
        student s5 = new student("邓憨憨3",43);
        m.put(1,s1);
        m.put(2,s2);
        m.put(3,s3);
        m.put(4,s4);
        m.put(5,s5);
        m.remove(5);//移除
        //m.clear();//清楚集合
        Set<Integer> keys = m.keySet();
        boolean b = m.containsKey(4);
        boolean b1 = m.containsValue(s2);
        System.out.println(b1);
        System.out.println(b);
        Collection<student> values = m.values();
        for (student value : values) {
            System.out.println(value);

        }
        Set<Map.Entry<Integer, student>> entries = m.entrySet();
        for (Map.Entry<Integer, student> entry : entries) {
            System.out.println(entry);

        }
        for (Integer key : keys) {
            student s = m.get(key);//根据键获取值
            System.out.println("键:"+key+"   "+"值:"+s);

        }

    }

}

泛型

泛型的理解机注意事项

标签:说明这是什么 指定集合数据类型 :指代任意数据类型

  1. 集合中使用:集合接口和类都是带泛型的结构
  2. 实例化集合类,可以指明具体的泛型类型
  3. 指明完后,集合类和接口中的泛型变为指明的数据类型
    add(E e) add(String e)
  4. 泛型的类型必须是类,不能是基本数据类型,如若是基本数据类型则使用他们的包装类
    没有指明泛型类型,默认是Objectl类型
泛型类
public class DAO<T> {
    private Map<String,T> map = new HashMap<>();

泛型方法

使用泛型不等与泛型方法

public <E> List<E> copyArray(E[] arr){
            ArrayList<E> es = new ArrayList<>();
            for (E e : arr) {
                es.add(e);
            }
            return es;
        }
泛型实例

访问数据库(表=对象 申明一个类)

  1. 创建一个泛型类DAO,创建一个MAP集合,key为String value为T对象,创建相关方法
package com.lcj.集合.text;

import java.util.*;

public class DAO<T> {
    private Map<String,T> map = new HashMap<>();
    //保存T类型的对象到Map集合中
    public void save(String id,T entity){
        map.put(id,entity);
        System.out.println("id:"+id+"\t\t保存成功");
    }

    //从map集合中获取id对应的对象
    public T get(String id){
        T t = map.get(id);
        return t;
    }

    //替换map集合中key为id的内容,改为entity对象
    public void update(String id,T entity){
        if(map.containsKey(id)){
            map.put(id,entity);
        }
    }

    //返回map集合中存放的所有T对象
    public List<T> list(){
        ArrayList<T> ts = new ArrayList<>();
        Collection<T> values = map.values();
        for (T value : values) {
            ts.add(value);
        }
        return ts;
    }

    //删除指定对象
    public void delete(String id){
        map.remove(id);
    }
}
  1. 创建一个User类
package com.lcj.集合.text;

public class User {
    private int id;
    private int age;
    private String name;

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

    public int getId() {
        return id;
    }

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

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

  1. 创建测试类
package com.lcj.集合.text;

import java.util.List;

public class DaoText {
    public static void main(String[] args) {
        DAO<User> userDAO = new DAO<>();
        userDAO.save("1001",new User(1001,23,"朱俊良"));
        userDAO.save("1002",new User(1002,24,"张俊"));
        userDAO.save("1003",new User(1003,25,"刘成军"));
        userDAO.save("1004",new User(1004,26,"吕豪"));
        userDAO.save("1005",new User(1005,27,"胡明雄"));
        userDAO.save("1006",new User(1006,28,"王飞翔"));
        User user = userDAO.get("1003");
        System.out.println(user);

        userDAO.update("1004",new User(1004,18,"邓婷婷"));
        userDAO.delete("1006");

        List<User> list = userDAO.list();
        for (User user1 : list) {
            System.out.println(user1);

        }


    }
}

遍历集合的两种方式

增强for循环:简化遍历 快捷键:集合.for
迭代器:过程的重复,应用于对集合的遍历
可认为指针的移动

        List lt = new ArrayList();
        lt.add("a");
        lt.add("b");
        lt.add("c");
        Iterator ie = lt.iterator();//普通迭代器只能用来遍历
        while (ie.hasNext()){//判断是否有元素
            System.out.println(ie.next());
        }

补充:listIterator()迭代器

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值