第五次实验室周报

数据结构简述

数据结构:把多个数据按照一定的存储方式,存储起来,称存储方法为数据结构。
数组是最简单的数据结构。
数据的存储方式有:数组,队列,链表,栈,哈希表等。
不同的数据结构性能不同,所以要选比较合适的,不能乱用。
数据结构的作用:
1:最基本的作用:可以对应用中多个数据做存储(模拟生活数据的存储)。
2:面向对象设计:作为程序员开发的中间工具。

浅谈集合

一、 Vector : 是一个动态数组,其底层依然是一个Object[ ] 数组,和我们编写的MyArrayList是一样的,既然是对数组做封装,所以包含了对数组的增删改查操作。
Vector和ArrayList的关系:
1):底层算法都基于数组。
2):ArrayList是集合框架里提供的新的变长数组,Vector是ArrayList的前身。
3):Vector相对于ArrayList来说,线程更安全,但性能较低。

public class VectorDemo {
    public static void main(String[] args) {
        Vector vector=new Vector(10);
        //boolean add(E e)将指定元素添加到此Vector的末尾。
        //void add(int index, E element)在此Vector的指定位置插入指定的元素。
        //void addElement(E obj)将指定的组件添加到此Vector的末尾,将其大小增加 1。
        vector.add("A");
        vector.addElement("B");
        // add方法和 addElement方法差不多(通过看底层源码)
        System.out.println(vector);// 直接调用toString方法
        vector.add(0,"C");
        System.out.println(vector);
        //boolean addAll(Collection c)
        Vector v1=new Vector();
        v1.add(1);
        v1.add(2);
        v1.add(3);
        vector.add(v1); // 把 v1 当做整体存放在 vector 中
        vector.addAll(v1);// 把 v1的每一个元素存放在 vector中
        System.out.println(vector);
        //boolean contains(Object o) 判断当前集合是否包含元素 o
        System.out.println(vector.contains(1));
        //boolean containsAll(Collection c) 判断当前集合是否包含集合 o
        System.out.println(vector.contains(v1));

        // 集合里面存放的是对象的引用,而不是对象的数据(通过地址来实现操作)
        Vector v2=new Vector();
        StringBuilder str=new StringBuilder("Will");
        v2.add(str);
        System.out.println(v2);
        str.append("lalala");
        System.out.println(v2);

    }
}

拓展:在集合中,只能存储对象,不能存储基本数据类型。
也就是说,byte , short , char , int , long , float , double , boolean不能支持。
Java5之前,我们使用集合来存储数据,得自己装箱。
例如:集合对象.add(Integer valueOf(1));
但是java5开始,可以自动装箱;
例如:集合对象.add(1);

二、 栈:底层依然是数组:
特点:先进后出(LIFO)
三个操作:
1、压入到栈顶 :push
2、弹出栈顶元素 :peek
3、移除栈顶元素 :pop
Java.until.Stack是Vector的子类。

三、 基于数组的集合类,如ArrayList的构造器:
Public ArrayList() {}
Public ArrayList(int initialCapacity) {}
扩容问题:
Public ArrayList() {}
在以前,默认创建的是一个容量为10的数组,底层:this(10);
现在默认创建的是一个没有元素的空数组。底层:new Object[] {}。虽然创建了没有元素的空数组,但是当第一次使用add方法的时候,此时才设定初始容量为10。

四、 LinkedList类:底层使用的单链表操作/双向链表/单向队列/双向队列。并且与头插,尾插以及频繁改变元素相关的操作十分方便。

五、 集合继承体系( 以后会贴一张详细继承图 ):
Iterable接口:支持集合的迭代操作。
Collection接口:表示集合/容器。
Collection接口有两个非常重要的子接口:List/Set。

List接口:表示一种,可以允许元素重复,并且会记录添加顺序的集合。
最常用的实现类:ArrayList,LinkedList。
Set接口:表示一种,不允许元素重复,并且也不会记录添加顺序的集合。
最常用的实现类:HashSet,TreeSet。对于Set接口的实现类中,去重操作只对基本类型有效,对于自定义类的对象的去重必须重写equals和hasCode方法。

六、 迭代器和增强for循环:

public class IteratorDemo {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        System.out.println(list);
        // 取出集合中的各元素 (传统做法)
        for(int i=0;i<list.size();i++){    // 第一种方法
            Object ele=list.get(i);
            System.out.println(ele);
        }
        System.out.println("-----------------------------------");

        // 更佳做法:使用迭代器
        Iterator it=list.iterator();       //第二种方法
        while(it.hasNext()){              //判断是否有下一个元素
            System.out.println(it.next());//  让指针指向下一个元素
        }
        System.out.println("---------------------------------------");
        /* 另外一种操作
        for(Iterator it=list.iterator();it.hasNext();){
            System.out.println(it.next());-------------->这里会自增
        }
        此时 it 对象在for循环结束就销毁,相比于在方法里创建迭代器对象,空间使用更合理。
         */

        Vector v=new Vector();            //第三种方法
        v.add(1);
        v.add(2);
        v.add(3);
        Enumeration elements=v.elements();// 此接口的功能与 Iterator 接口的功能是重复的,新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。
        while(elements.hasMoreElements()){
            System.out.println(elements.nextElement());
        }
        System.out.println("---------------------------------------");

        // 最简单的迭代方式
        for(Object ele : list){
            System.out.println(ele);
        }
        /*
        for(Object ele : 数组 / Iterable接口的实现类的的对象){
            System.out.println(ele);
        }
         */
    }
}

增强for 循环(for-each循环):
for(Object ele : 数组 / Iterable接口的实现类的的对象){
System.out.println(ele);
}
操作数组的时候:底层其实就是普通的for循环。
操作集合的时候:底层使用的是Iterator迭代器。

七、 Set接口:

public class SetDemo {
    public static void main(String[] args) {
        Set set=new HashSet();
        set.add("A");  // 重复的元素被覆盖掉了
        set.add("A");
        set.add("A");
        set.add("B");
        System.out.println(set);

        // Set-->List
        List list=new ArrayList(set);
        list.add("C");
        list.add("A");
        System.out.println(list);

        //List-->Set
        Set set1=new HashSet(list);
        System.out.println(set1);

    }
}

HashSet类:

class Student extends Object{
       private String name;
       private Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
// ctrl+ins生成          是否为同一对象的评判可以调控:选择name 或者 age 作为评判,默认是两个一起的
    //这里改写为 name
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name);
    }
}

/*
在哈希表中,每一个对象的存储位置是不同的,通过对象的hashCode()和equals()决定( hashCode值相同,equals为true时,才被认为是同一个对象)。
 */

public class HashSetDemo2 {
    public static void main(String[] args) {
        Student stu1=new Student("赵大",1);
        Student stu2=new Student("赵大",2);
        Student stu3=new Student("孙三",3);
        Student stu4=new Student("李四",4);

        Set set=new HashSet();
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        System.out.println(set);

    }
}

LinkedHashSet类是HashSet类的子类:同时体现了双向链表和哈希表算法。
哈希表算法:决定了存储位置。
双向链表算法:用来保证在迭代时候的顺序就是插入时的顺序。
LinkedHashSet类相对于HashSet来说,性能更低,因为需要保证输出顺序。

// LinkedHashSet既要保证不能重复,又要保证输入有序。
public class LinkedHashSetDemo {
    public static void main(String[] args) {
        Set set=new HashSet();
        set.add("5");
        set.add("6");
        set.add("3");
        set.add("4");
        System.out.println(set);

        set=new LinkedHashSet();
        set.add("5");
        set.add("6");
        set.add("3");
        set.add("4");
        System.out.println(set);
    }
}

问题:为什么不直接使用List的实现类?
因为LinkedHashSet类不仅可以保证添加顺序还保证元素不能重复。

你可能感兴趣的:(java)