集合基础

容器

​ 容器

​ / \

​ Collection \ (接口)

​ / \ Map (接口)

​ Set List \ (接口)

​ | / \ \

​ HashSet LinkedList ArrayList HashMap (实现类)

容器:长度可以根据数据的多少动态的伸缩;可以存储任意类型的数据(引用数据类型)。

1.Collection接口

Collection是一个接口,只规定了一些方法,需要通过其实现类创建对象。

1.1主要方法

  • 添加 add
  • 删除 remove
  • 计数 size
  • 包含 contains
  • 清空 clear
  • 是否空 isEmpty

1.2遍历方式

  • 增强for循环;
  • 迭代器:

​ 1)获取迭代器对象(获取遍历当前集合的迭代器对象);

​ 2)判断是否存在下一个元素;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class collectiondemo {
    public static void main(String[] args) {
        Collection col = new ArrayList();//多态,Collection接口指向ArrayList对象
        Collection col2 = new ArrayList();
        //多态添加元素
        col.add("asd0");
        col.add(123);
        col.add('a');
        col.add(true);
        col.add(new Student());
        System.out.println(col);
        col2.add("aaa");
        col2.add('a');
        col2.add(123);
        //添加另一个集合
        col.addAll(col2);
        System.out.println(col);
        //Iterator遍历方式
        Iterator it = col.iterator();//获取迭代器对象
        while(it.hasNext()){//判断是否有下一个值
            System.out.println(it.next());//打印集合中的内容
        }
        System.out.println("==========");
        //增强for循环遍历
        for(Object obj:col){
            System.out.println(obj);
        }
        System.out.println("============");
        //移出与()中集合交集的元素
        col.removeAll(col2);
        System.out.println(col);

    }
}
class Student{
private int age;
private String name;
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

2.List接口

List接口有序且可重复,且新增了一些根据索引操作的方法。

泛型的作用:提高安全性、规范性,达到类型检查的作用。

2.1遍历方式

  • 普通for循环,如果使用增强for循环和迭代器时会导致内部并发指向同一个对象,会产生异常。
  • ListIterator—List接口独有迭代器;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Avengers {
    public static void main(String[] args) {
        List<String > li = new ArrayList<>();
        li.add("IronMan");
        li.add("灭霸");
        li.add("SpiderMan");
        li.add("灭霸");
        li.add("Holk");
        li.add("灭霸");
        li.add("约翰逊");
        li.add("灭霸");
        System.out.println(li);
        //正常for循环可以遍历,增强for循环不可以遍历,因为会并发指向同一个对象
        for(int i = 0;i<li.size();i++){
            System.out.println(li.get(i));
        }
        System.out.println("==============");
        //list专用迭代器,倒序遍历前必须正序遍历,使指针停留在最后一个元素上
        //正序遍历
        ListIterator<String> lii = li.listIterator();
        while(lii.hasNext()){
            if("灭霸".equals(lii.next())){
                lii.add("惊奇队长");
            }
        }
        //倒序遍历
        while(lii.hasPrevious()){
            System.out.println(lii.previous());
        }
        System.out.println(li);

    }
}

值得注意的是:在使用倒序遍历时需要先正向遍历将指针移到最后一个元素的位置,否则不会从最后一个元素遍历。

3.ArrayList实现类

优点:根据索引查询,修改效率高;

缺点:做增加删除时效率低;

应用场景:大量做查询少量做增删的时候适合用ArrayList;

扩容机制:int newCapcity = old Capcity + (oldCapcity>>2) 每次扩容原容量1.5倍;

同步:线程不安全的|不同步的

import java.util.ArrayList;
import java.util.Arrays;
import java.util.ListIterator;

public class Practice {
    public static void main(String[] args) {
        //创建Employee对象
        Employee e1 = new Employee("张三",10000);
        Employee e2 = new Employee("李四",8000);
        Employee e3 = new Employee("王五",15000);
        //通过调用方法,设置Employee对象的工作状态
        getStatus(e1,Status.BUSY);
        getStatus(e2,Status.NORMAL);
        getStatus(e3,Status.FREE);
        //创建ArrayList对象
        ArrayList<Employee> al = new ArrayList();
        //增加元素
        al.add(e1);
        al.add(e2);
        al.add(e3);
        System.out.println(al);
        //遍历ArrayList,工作状态为FREE的员工扣工资
        for(int i =0;i<al.size();i++){
            if(Status.FREE.equals(al.get(i).getStatus())){
                al.get(i).setSalary(al.get(i).getSalary()-1000);
            }
        }
        System.out.println(al);
        //通过List迭代器遍历,删除元素
        ListIterator<Employee> li = al.listIterator();
        while(li.hasNext()){
            if(li.next().getSalary()>=10000){
                li.remove();
            }
        }
        System.out.println(al);
    }
    //为员工增加工作状态的方法
    public static void getStatus(Employee emp,Status status){
        emp.setStatus(status);

    }
}

//Employee类
class Employee{
    private String name;
    private int salary;
    private  Status status;

    public Employee(){

    }
    public Employee(String name,int salary){
        this.name = name;
        this.salary = salary;

    }

    public String getName() {
        return name;
    }

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

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", status=" + status +
                '}';
    }
}
//枚举类
enum Status{
    BUSY,NORMAL,FREE;
}

4.Vector实现类

也是通过数组存储数据,与ArrayList特点相同。

不同点:

  • 线程安全的|同步的,如果不需要线程安全实现,建议使用ArrayList代替Vector;
  • Vector每次扩容原容量2倍,ArrayList每次扩容原容量1.5倍,ArrayList有利于节省空间;

5.Set接口

无序且不可重复,存储数据的顺序与添加的顺序不同,没有新增方法。

import java.util.HashSet;
import java.util.Set;

public class SetDemo {
    public static void main(String[] args) {
        //泛型规定集合中所有数据类型为String类型
        Set<String> set = new HashSet<String>();
        set.add("ab");
        set.add("bc");
        set.add("cd");
        set.add("cd");
        set.add("cd");
        set.add("指针");
        set.add("指针");
        set.add("bd");
        set.add("be");
        set.remove("cd");
		//去重且顺序与添加顺序不同
        System.out.println(set);
    }
}

6.TreeSets实现类

底层结构:红黑树(平衡二叉树)

特点:有序(存储数据默认升序),存放的顺序与内部存储的顺序不同

6.1比较器

内部比较器|自然排序:

  • 自定义类需要实现Comparable接口,重写compareTo方法;

外部比较器|定值排序:

  • 重新定义类,实现Comparator接口,重写compare方法,方法中定义规则。在定义TreeSet对象的时候将此类对象作为参数传入。

在Set进行排序时会首先选择默认比较器,即内部比较器。

内部比较器应用:

public class TreeSet {
    public static void main(String[] args) {
        Person p1 = new Person("张三",5000);
        Person p2 = new Person("李四",10000);
        Person p3 = new Person("王五",3000);
        //自定义类型
        Set<Person> set = new java.util.TreeSet<Person>();
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);
        //泛型:String类型
        Set<String> set2 = new java.util.TreeSet<String>();
        set2.add("123");
        set2.add("abc");
        set2.add("a1");
        set2.add("b2");
        //默认升序
        System.out.println(set2);
/*        Set set3 = new java.util.TreeSet();
        set3.add(123);
        set3.add("abc");
        set3.add('a');
        set3.add("b2");
        System.out.println(set3);*/

    }
}
class Person implements Comparable{//内部比较器首先要在自定义类开始实现Comparable接口

    private int salary;
    private String name;

    public Person() {
    }

    public Person(String name,int salary) {
        this.salary = salary;
        this.name = name;
    }
    //内部比较器
    @Override
    public int compareTo(Object o) {//重写compareTo方法
        int check = this.getSalary()-((Person)(o)).getSalary();//类型转换
        if(check>0){
            return 1;
        }else if(check <0){
            return -1;
        }else{
            return 0;
        }

    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

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

外部比较器:

import java.util.Comparator;
import java.util.Set;

public class TreeSet02 {
    public static void main(String[] args) {
        Person p1 = new Person("张三",5000);
        Person p2 = new Person("李四",10000);
        Person p3 = new Person("王五",3000);
        Set<Person> set = new java.util.TreeSet<Person>(new Check());
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);
    }
}
//外部比较器  
class Check implements Comparator<Person> {//创建新类实现Comparator接口,且泛型是自定义类型
    @Override
    public int compare(Person o1, Person o2) {
        //判断条件
        if(o1.getSalary()>o2.getSalary()){
            return -1;
        }else if(o1.getSalary()<o2.getSalary()){
            return 1;
        }else{
            return 0;
        }
    }
}

内部比较器与外部比较器的区别:

外部比较灵活,便于后期维护;

内部比较器若要改变比较规则,每次都需要修改源代码,耦合度高,不便于后期维护。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值