Java—类集1

Java—类集1

1.什么是类集?

类集是为了解决数组长度固定的问题而产生的,

其本质就是一个用动态的对象数组实现的框架—Java类集框架。

可以说累计就是动态数组。

类集下有两个核心接口:

1.Collections 2.Map;

##Collections

1.Collection下有几个核心方法:

方法内容
public boolean add(E e)向集合中添加元素
public boolean remove(Object o)删除指定元素
public boolean contains(Object o)类集中是否包含指定元素
public Object[] toArray()将集合变为对象数组
public int size()返回集合中元素个数
public Iterator iterator()获取集合的Iterator接口对象

##子接口List

List接口有两个独有的方法:

方法内容
public E set(int index, E element)设置固定索引的值
public E get(int index)取得指定索引的值

1.有三个具体子类

ArrayList:版本JDK1.2,底层由数组实现,采用异步处理,性能较高,线程不安全,可以采用Iterator 、ListIteraror、foreach,初始化机制,lazy-load 每当add()方法添加一个元素后才会初始化,初始值为10,

并且每次扩容1.5

LinkedList:版本JDK1.0,底层由双向链表实现,才用异步处理,性能较高,线程不安全,但是由于底层是链表,性能高,可以采用Iterator 、ListIteraror、foreach

Vector:版本JDK1.0,底层由数组实现,采用同步处理,性能较低,但是线程安全,可以采用Iterator 、ListIteraror、foreach、Enumeration 当有一个实例化Vector就会初始化一个容量为10 的Vector。

我们可以看出,向集合内添加的是java自带的类型,那么,我们在查找和删除时可以找到,但如果是自定义类型,就必须覆写equals()方法:

class Person{
    private String name;
    private Integer age;

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test{
    public static void main(String[] args) {
        ArrayList<Person> list=new ArrayList<>();
        list.add(new Person("张三",19));
        list.add(new Person("李四",10));
        list.add(new Person("王麻子",0));
        System.out.println(list.contains(new Person("张三",19)));
    
    }
}

如果覆写equals ,那么就相当于两个不同的对象在比较,所以即使内容一样,比较结果也是不同的,而我们想要比较的是内容。

2.迭代器输出
迭代器接口有Iterator ,ListI,Enumeration
Iterator:
Enumeration:v只提供了遍历Vector和HashTable类型集合元素的功能,不支持元素的移除操作。
ListIterator:针对List的迭代器ListIterator,该迭代器只能用于各种List类的访问。
可以双向访问。

1.获取迭代器接口对象

2.迭代器接口对象有三个方法

方法解释
boolean hasNext()是否有下一个元素
E next()取得下一个元素
default void remove()删除元素
public class Test{
    public static void main(String[] args) {
        ArrayList<Person> list=new ArrayList<>();
        list.add(new Person("张三",19));
        list.add(new Person("李四",10));
        list.add(new Person("王麻子",0));
        System.out.println(list.contains(new Person("张三",19)));
        Iterator iterator=list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

在迭代器输出的时候,有如果有list.remove() 操作,会抛出ConcurrentModificationException

但是Iterator为我们提供了 iterator.remove()方法来避免出错。

实际上,如果是线程安全的集合 比如Vector就不会出现这个问题。

上述例子ArrayList采用的是异步操作,也就是说多个允许线程访问,如果一个线程删除一个数据,别的线程拿到的是不完整的数据,所以出现脏读,不允许删除。

所以 ,java采用一种fast–fail操作,保证用户在进行迭代遍历时数据一定输最新的。

通过查看原码,ArrayList里有一个modCount来记录集合的修改次数,

在取得迭代器接口时,会创建一个副本expectedModCount,来记录当前集合修改次数,如果使用remove,add,set等方法修改集合modCount就会自增,而每次迭代器输出的时候,会检查modCount和expectedModCount是否相等,所以如果不相等,那么就会抛出ConcurrentModificationException ,

这样保证每次输出都是最新的。

Colletions工具类有一个synchronizedList ()

可以将线程不安全的转换成线程安全的 但是不建议使用 如果要使用

就用CopyonWriteArrayList

子接口Set(数据不允许重复)

set接口下有两个具体的子类

HashSet,和TreeSet

其中他们的区别是TreeSet是有序的,而HashSet是无序的

同样,如果是java已有的类型添加或删除到Set中,可以自动去重或排序,但是如果是自定义类型,一定要覆写hashCode和equals 并且如果是TreeSet类型,加入集合元素一定要实现Compareble接口并且覆写里面的CompareTo 或者在构造器中传入一个Comparator() 比较器

class Person {
    private String name;
    private Integer age;

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

    public String getName() {
        return name;
    }
    public Integer getAge() {
        return age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&
                Objects.equals(age, person.age);
    }
    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Test{
    public static void main(String[] args) {
        TreeSet<Person> treeSet=new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((Person)o1).getAge()-((Person) o2).getAge();
            }
        });
        treeSet.add(new Person("a",19));
        treeSet.add(new Person("b",18));
        treeSet.add(new Person("c",20));
        treeSet.add(new Person("d",21));
        treeSet.add(new Person("d",21));
        Iterator iterator=treeSet.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值