Java类集基础概念-Collection接口及其子类

23 篇文章 0 订阅

类集复习

动态数组

1.基于数组实现

import java.util.Arrays;
​
/**
 * @Author:Star
 * @Date:Created in 8:05 2019/4/16
 * @Description:自己实现的动态数组
 */
public class MyArray<E> {
    //数组默认容量大小
    private final static int DEFAULT_CAPACITY = 10;
    //存放元素的数组
    private E[] elementData;
    //数组元素的大小
    private int size;
​
    public MyArray(){
        this(DEFAULT_CAPACITY);
    }
​
    public MyArray(int initCap){
        elementData = (E[]) new Object[initCap];
    }
​
    public void add(E e){
        if(size == elementData.length){
            //扩容
            int oldCap = elementData.length;
            int newCap = oldCap+((size>64)?(oldCap >> 1):oldCap);
            if(newCap > Integer.MAX_VALUE - 8){
                throw new IndexOutOfBoundsException("数组元素过多");
            }
            elementData = Arrays.copyOf(elementData,newCap);
        }
        elementData[size++] = e;
    }
    
}

2.基于链表实现

public class MyArrayBasedOnListedList<E> {
    private class Node{
        E data;
        Node next;
        Node prev;
​
        public Node(E data, Node next, Node prev) {
            this.data = data;
            this.next = next;
            this.prev = prev;
        }
    }
    
    //链表元素的大小
    private int size;
    //头节点
    private Node head;
    //尾节点
    private Node tail;
    
    //插入操作
    public void add(E e){
        Node node = new Node(e,null,tail);
        if(tail == null){
            head = tail = node;
        }
        tail.next = node;
        tail = node;
        size++;
    }
    
}

Collection

1.出现版本

JDK1.2

2.解决问题

数组定长问题

3.定义

Collection接口是Java中保存单个对象的最顶层接口

4.继承关系

 

5.常用操作方法

  • 添加元素:boolean add(E e);

  • 删除元素:boolean remove(Object o);

  • 查找元素:boolean contains(Object o);

  • 取得集合大小:int size();

  • 转为数组:Object[] toArray();

  • 取得类集的迭代器:Iterator<E> iterator();

List

1.独有方法

index默认从0开始编号

  • 根据索引下标取得元素:E get(int index);

  • 根据索引下标修改元素,返回修改前的数据:E set(int index,E element);

2.空集合(含有空元素)

Collections.EMPTY_LIST

3.添加自定义类

List集合中添加自定义类

使用contains()、remove()需要equals()的支持

举个栗子,比如使用contains()方法时需要查找对象张三在不在列表中:如下

class Person{
    private String name;
    private int age;

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

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

public class listTest {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("张三",12));
        list.add(new Person("李四",13));
        list.add(new Person("王五",14));
        System.out.println("list中是否包含张三:"+list.contains(new Person("张三",12)));
    }
}

4.子类及其关系

ArrayList、Vector、LinkedList的区别:

ArrayList:Vector区别

 ArrayListVector
出现版本JDK1.2JDK1.0
调用无参构造懒加载策略,在构造方法阶段并不初始化对象数组,第一次添加元素时初始化对象数组大小为10产生对象时,内部数组初始化为10的数组
扩容策略新数组大小变为原数组的1.5倍新数组大小变为原数组的2倍
线程安全性异步处理,线程不安全,效率较高在方法上加锁(synchronized同步方法),线程安全,效率较低(锁的是当前Vector对象,当前对象的所有方法均上锁,其他线程不可调用)
遍历不支持较老的迭代器Enumeration支持较老迭代器Enumeration
特殊 JDK内置的Stack继承Vector

1.出现版本:

ArrayList JDK1.2

Vector JDK1.0(出现在List、Collection接口之前)

2.调用无参构造

Vector在无参构造执行后将对象数组大小初始化10

ArrayList采用懒加载策略,在构造方法阶段并不初始化对象数组,

在第一次添加元素时才初始化对象数组大小为10

3.扩容策略

ArrayList:扩容时,新数组大小变为原数组的1.5倍

int newCapacity = oldCapacity + (oldCapacity >> 1);

Vector:扩容时,新数组大小变为原数组的2倍

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);

4.线程安全性:

ArrayList采用异步处理,线程不安全,效率较高

Vector采用在方法上加锁,线程安全,效率较低(即使要使用线程安全的List,也不用Vector)

public synchronized boolean add(E e){}

5.遍历区别

Vector支持较老的迭代器Enumeration,ArrayList不支持

 

ArrayList、Vector的共同点

底层均使用数组实现

遍历时都支持Iterator/ListIterator/foreach

 

ArrayList、LinkedList区别

LinkedList底层采用双向链表实现(不存在扩容操作);特殊:是JDK Queue的一个子类(适用于增删频繁的情况下)

ArrayList底层采用数组实现(适用于经常查找的情况下)

 

ArrayList、LinkedList共同点

线程安全性:异步处理,线程不安全,效率较高

 

Set

不允许数据重复

本质是Map接口

public TreeSet() {
        this(new TreeMap<E,Object>());
    }

只实现了Collection接口,并没有对其扩充

1.常用子类

2.TreeSet

  • 底层实现:红黑树

  • 有序存储--按照升序存储;

  • 不允许存放null;

  • 不允许数据重复:利用实现Comparable接口/传入外部比较器接口的返回值判断是否重复

2.1升序存储

自定义类要想使用TreeSet,前提:

要么自定义类自己实现了Comparable接口

要么从外部传入一个该类的比较器对象,该类的比较器类实现了Comparator接口

2.2排序

2.2.1Comparable接口

(1)java.lang.Comparable:内部排序接口

(2)类实现了Comparable表示此类具备可比较的性质

(3)比较方法compareTo(T o);

public int compareTo(T o) {}

返回正数:表示当前对象>目标对象

返回0:表示当前对象=目标对象

返回负数:表示当前对象<目标对象

2.2.2Comparator接口

(1)java.util.Comparator:外部排序接口(策略模式

(2)类本身不具备可比较的特性,专门有一个类来比较自定义类的大小

(3)

public int compare(T o1,T o2) {}

返回正数:表示当前对象>目标对象

返回0:表示当前对象=目标对象

返回负数:表示当前对象<目标对象

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
​
class Person{
    private Integer age;
    private String name;
​
    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }
​
    public Integer getAge() {
        return age;
    }
​
    public String getName() {
        return name;
    }
}
​
/*按照年龄升序排序,实现了外部比较器Comparator接口*/
class PersonAgeSec implements Comparator<Person>{
​
    @Override
    public int compare(Person o1, Person o2) {
        if(o1.getAge() > o2.getAge()){
            return 1;
        }
        if(o1.getAge() < o2.getAge()){
            return -1;
        }
        return 0;
    }
}
​
public class setTest {
    public static void main(String[] args) {
        PersonAgeSec p = new PersonAgeSec();
        Set<Person> set = new TreeSet<>(p);
        set.add(new Person(20,"A"));
        set.add(new Person(23,"y"));
        set.add(new Person(21,"B"));
        System.out.println(set);
    }
}

3.HashSet

  • 无序存储

  • 不允许元素重复:使用equals()与hashcode()共同判断元素是否重复

equals():判断对象的属性是否相等

hashcode():对象在内存中的地址根据hash算法转为int

  
 //判断对象的属性值是否相等
   public boolean equals(Object o){
        if(this == o){
            return true;
        }
        if(!(o instanceof Person)){
            return false;
        }
        Person p = (Person) o;
        return this.age.equals(p.age)
                && this.name.equals(p.name);
    }
    //判断地址是否相等
    public int hashCode(){
        return Objects.hash(name,age);
    }   

equals()和hashCode()的关系

equals()相同,hashCode一定相同

hashCode()相同,equals不一定相同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值