Java 8 day--java容器,java集合框架,Collection接口,List接口,Set接口、Comparable接口、泛型

为什么使用集合框架?
java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。

接口(增删改查)

Collection接口

存储一组不唯一、无序的对象。

特点:
1.可以存放不同类型的数据,
2.当使用arraylist子类实现的时候,初始化长度是10,长度不够时进行扩容操作。

api方法:
add: 要求必须传入的参数是Object对象,因此当写入基本数据类型的时候,包含了自动拆箱和自动装箱的过程。

  •    Collection collection=new ArrayList();
       collection.add(1);
    

addAll: 添加另一个集合到此集合中。

  •    Collection collection1=new ArrayList();
       collection1.add("a");
       collection.addAll(collection1);
    

clear: 只是清空集合中的元素,但是次集合对象并没有被回收。

  •    collection.clear();
    

remove: 删除指定元素。

  •    collection.remove("a");
    

removeAll: 删除集合元素。

  •    collection.removeAll(collection);
    

contains: 判断集合中是否包含指定的元素值。

  •    System.out.println(collection.contains("a"));
    

containsAll: 判断此集合中是否包含另一个集合。

  •   System.out.println(collection.containsAll(collection1));
    

isEmpty: 判断集合是否等于空

  •    System.out.println(collection.isEmpty());
    

retainAll: 若集合中拥有另一个集合的所有元素,返回true,否则,返回false。

  •    System.out.println(collection1.retainAll(collection));
    

size: 返回当前集合的大小。

  •    System.out.println(collection.size());
    

toArray: 将集合转换成数组。

  •    collection.toArray();
       //转换对应类型
       Object[] objects = collection.toArray();
    

List与Set接口(Collection子接口)

List接口存储一组不唯一、有序(插入顺序)的对象。
Set接口存储一组唯一、无序的对象。
Map接口存储一组键值对象,提供key到value的映射。

List

        List list=new ArrayList();
        list.add("a");
        list.add("1");
        list.add("a");
        list.add("true");
        //[a, 1, a, true]
        System.out.println(list);
        //a
        System.out.println(list.get(0));
        //0
        System.out.println(list.indexOf("a"));
        //2
        System.out.println(list.lastIndexOf("a"));
        list.set(0,"mm");
        //[mm, 1, a, true]
        System.out.println(list);
        List list1=list.subList(0,2);
        //[mm, 1]
        System.out.println(list1);
//        List of=List.of(1,2,3,4);

ArrayList:
实现了长度可变的数组,在内存中分配连续的空间。
-优点:遍历元素和随机访问元素的效率比较高。
-缺点:添加和删除需要大量移动元素效率低,按照内容查询效率高。
LinkList:
采用链表存储方式。
-优点:插入、删除元素时效率比较高。
-缺点:遍历和随机访问元素效率低。
Vector:
Vector也是List接口的一个子类实现。
Vector跟ArrayList一样,底层都是使用数组进行实现。
Vector和ArrayList区别:
(1)ArrayList是线程不安全的,效率高,Vector线程安全。
(2)ArrayList在进行扩容的时候是扩容1.5倍,Vector扩容原来的2倍。

Set

set中存放的是无序,唯一的数据。
set不可以通过下标获取对应位置的元素值。
使用treeset底层的实现是treemap,利用红黑树来进行实现。
设置元素的时候,如果是自定义对象,会差找对象中的equals和hashCode的方法
,如果没有,比较的是地址。
树中的元素是要默认进行排序操作的,如果是基本数据类型,自动比较;如果是引用类型的话,需要自定义比较器。

HashSet:
采用Hashtable哈希表存储结构。
-优点:添加速度快,查询速度快,删除速度快。
-缺点:无序。
-LinkedHashSet:
–采用哈希表存储结构,同时使用链表维护次序。
–有序(添加顺序)。
HashSet存储了相同对象,不符合实际情况:重写equals和hashCode方法。
TreeSet:
采用二叉树(红黑树)的存储结构。
-优点:有序(排序后的升序),查询速度比List快。
-缺点:查询速度没有HashSet快。

Iterator接口(Collection子接口)

常规的循环:do…while、while、for;还有一种增强for循环的方式,可以简化循环的编写。
所有的集合类都默认实现了Iterable的接口,实现此接口意味着具备了增强for循环的能力,也就是for-each。
增强for循环本质上是用的也是iterator的功能。
-方法:iterator()和foreach()
iterator的方法中,要求返回一个Iterator的接口子类实例对象,此接口中包含了hasNext()和next()。

在使用iterator进行迭代的过程中如果删除其中的某个元素会报错并发操作异常,如果遍历的同时要修改元素,建议使用listIterator()。
listIterator()迭代器提供了向前和向后两种遍历方式,始终是通过cursor和laster的指针来获取元素值及向下遍历索引,当使用向前遍历的时候必须要保证指针在迭代器的结果,否则无法获取结果值。

//        Iterator iterator = list.iterator();
        ListIterator iterator = list.listIterator();
        while(iterator.hasNext()){
            Object o=iterator.next();
            if (o.equals(1)){
                iterator.remove();
            }
            System.out.println(o);
        }

Comparable接口

此比较器按照name的长度来进行比较。

比较器分类:

-内部比较器
定义在元素的类中,通过实现comparable接口来进行实现。

Person.java:

public class Person implements Comparable{
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        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 age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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

    @Override
    public int compareTo(Object o) {
        Person p=(Person) o;
        if(p.name.length()<this.name.length()){
            return 1;
        }else if(p.name.length()>this.name.length()){
            return -1;
        }else {
            return 0;
        }
    }

}

SetDemo.java:

public class SetDemo{
    public static void main(String[] args) {


        TreeSet treeSet = new TreeSet();

        treeSet.add(new Person("ooop", 12));
        treeSet.add(new Person("io", 9));
        treeSet.add(new Person("kdlsjf", 13));
        treeSet.add(new Person("fio", 14));
        System.out.println(treeSet);
    }

}

-外部比较器
定义在当前类中,通过实现comparator接口来实现,但是要将比较器传递到集合中。

Person.java:

public class Person /*implements Comparable*/{
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        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 age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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

//    @Override
//    public int compareTo(Object o) {
//        Person p=(Person) o;
//        if(p.name.length()<this.name.length()){
//            return 1;
//        }else if(p.name.length()>this.name.length()){
//            return -1;
//        }else {
//            return 0;
//        }
//    }

}

SetDemo.java:

public class SetDemo implements Comparator<Person>{
    public static void main(String[] args) {

        TreeSet treeSet = new TreeSet(new SetDemo());

        treeSet.add(new Person("ooop", 12));
        treeSet.add(new Person("io", 9));
        treeSet.add(new Person("kdlsjf", 17));
        treeSet.add(new Person("fio", 14));
        System.out.println(treeSet);
    }


    @Override
    public int compare(Person o1, Person o2) {
        if (o1.getAge()>o2.getAge()){
            return 1;
        }else if (o1.getAge()<o1.getAge()){
            return -1;
        }else {
            return 0;
        }
    }

}

注意:
如果两者同时存在,使用外部比较器。
当使用比较器的时候,不会调用equals方法。

泛型

当做一些集合的统一操作的时候,需要保证集合的类型是统一的,此时需要泛型来进行限制。
给集合中的元素设置相同的类型就是泛型的基本需求。
在定义对象的时候,通过<>中设置合理的类型来进行实现。

-优点:
1.数据安全;
2.获取数据时,效率高。

泛型的高阶用法:
1.泛型类
类中的方法的返回值类型和属性的类型都可以使用。

public class FanXingClass <A>{
    private int id;
    private A a;

2.泛型接口
(1)子类在进行实现的时候,可以不填写反省类型,此时在创建具体的子类对象的时候才决定使用什么类型。
FanXingDemo.java:

  •   FanXingInterfaceSub<Integer> fxi=new FanXingInterfaceSub<Integer>();
      fxi.test2(123);
    

FanXingInterfaceSub.java:

  • public class FanXingInterfaceSub<String> implements FanXingInterface<String>{
    

(2)子类在实现泛型接口的时候,只在实现父类接口的时候指定父类的泛型类型即可,此时测试方法中的泛型类型必须跟子类保持一致。

  • public class FanXingInterfaceSub implements FanXingInterface<String>{
    

3.泛型方法
在定义方法的时候,指定方法的返回值和参数是自定义的占用位,可以是类名中的T,也可以是自定义的Q,在返回值前面。
FanXingMethod:

public class FanXingMethod <T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public <Q> void show(Q q){
        System.out.println(q);
        System.out.println(t);
    }
}

4.泛型的上限
如果父类确定了,所有的子类都可以直接使用。
5.泛型的下限
如果子类确定了,子类的所有父类都可以直接传递参数使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值