java详解 --- 集合之数组实现和链表实现

来源:互联网 发布:js 代码高亮插件 编辑:程序博客网 时间:2024/06/05 09:40

一.List

在说数组实现和链表实现之前,先说说它们的”父亲” — List
List是可以有重复的数据存储的,按照顺序存储的,有下标.
List的特有方法:
1.添加 – add(int num,Object obj)
2.替换 – set(int num,Object obj)
3.获取 – get(int num)
4.删除 – remove(int num)
代码测试:

public static void fun1(){    List list = new List();    list.add("a");    list.add("b");    list.add("c");    list.add("d");    // 1.添加 -- add    // 想指定的索引处添加元素(记住不能越界数组)    list.add(1,"ly");    // 2.替换 -- set    // 替换指定的索引处的元素(不能越界 不能替换超出集合长度的索引处的元素)    list.set(3."yl");    // 3.获取 -- get    // 获取指定下标对应的元素(不能越界 不能获取超出集合长度的索引处的元素)    Object obj = list.get(2);    System.out.println("obj");    // 4.可以利用get方法遍历集合    for(int i= 0; i < list.size(); i++){        System.out.println(list.get(i));    }    // 5.删除 -- remove    // 按照索引删除索引出的元素    list.remove(2);    // 6.利用迭代器遍历数组    Iterator iterator = list.iterator();    while (iterator.hasNext()) {        //使用迭代器遍历的时候 next只能调用一次        System.out.print(iterator.next() + " ");    }}

结果为:
这里写图片描述

二.数组实现与链表实现

1.先说一个比较特殊的数组表现 – Vector
Vector是一个1.0版本数组实现的类,在1.2版本被ArrayList替代
Vector有特殊的遍历的方法 – 快速枚举遍历

Vector vector = new Vector();vector.addElement("a");vector.addElement("b");vector.addElement("c");vector.addElement("d");// 快速枚举遍历Enumeration elements = vector.elements();while(elements.hasMoreElements()){    // 获取下一个元素    // nextElement()也只会出现一次    System.out.print(elements.nextElement() + " ");}

结果为:
这里写图片描述

2.数组遍历(ArrayList)与链表遍历(LinkedList)
A.区别
数组遍历:查询快 增删慢
这里写图片描述
查询:根据数组的下标查找元素
增删:将元素放入数组中,就把要插入的位置的后面的所有的元素向后移一位,把元素放进去(删除的时候就把要删除位置的后面的全部元素向前移一位)
数组存放的规则:数组在创建的时候,会默认有10个位置.如果要存11个元素,那么就会创建一个新的数组,新数组的长度为原数组的1.5倍,然后把所有元素放进去.
链表遍历:查询慢 增删慢
这里写图片描述
1.链表中的元素分别保存了前一个元素地址和后一个元素的地址,通过这个元素可以找到前一个元素和后一个元素
2.查找的时候,先判断离头近还是离尾近
要是头近,就从头的位置一个一个想后找(用保存的地址)
要是尾近,就从尾的位置一个一个向前找(用保存的地址)
3.增删的时候,直接找要插入的位置,插进去,保存前后的元素的地址,后面的元素的地址都不变
B.什么时候用ArrayList?什么时候用LinkedList?
当你的功能是查询多的时候用ArrayList,当你的功能是增删多的时候选择用LinkedList.
代码举例:
1.ArrayList
①.需求:遍历数组(使用迭代器) [a,b,c,d]
如果数组中 有”b”这个元素 就添加”Oh-yes”这个元素

public static void fun2(){    List list = new ArrayList();    list.add("a");    list.add("b");    list.add("c");    list.add("d");    ListIterator listIterator = list.listIterator;    while(listIterator.hasnext()){        if(listIterator.next().equals("b")){            // 让迭代器自己去添加            listIterator.add("oh-yes");        }    }    // 一般在对集合的迭代的时候,不要轻易改变集合的长度    // 容易发生并发修改异常    // 解决方法:使用迭代器知己的修改方法    System.out,println(list);}

结果为:
这里写图片描述
②. 需求:在集合中存储6个学生, 分别两个涵涵 18岁 两个凉凉 16岁 两个星星 8岁,去除重复的.用封装函数的方法.
这个需求需要写两个类,用来添加学生

public static void main(){    ArrayList list = new ArrayList();    list.add(new Student("s1",1));    list.add(new Student("s1",1));    list.add(new Student("s2",2));    list.add(new Student("s2",2));    list.add(new Student("s3",3));    list.add(new Student("s3",3));    fun4();}public static void fun4(ArrayList list){    ArrayList newList = new ArrayList();    Iterator iterator = list.iterator();    while(iterator.hasnext()){        Object next = iterator.next();        // 这个函数的核心就是包含的判断        // contains的方法底层依赖于equals方法        // 而equals方法的基类比较的是地址是否相同        // 所以需要在Student类重写equals方法        // 不然是这个函数是无法达到要求的        if(!newList.contains(next)){            newList.add(next);        }    }    System.out.println(newList);}

人类

class Person{    private String name;    private int age;    //构造方法    public Person() {    }    public Person(String name, int age) {        this.name = name;        this.age = age;    }    // set/get方法    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;    }    // 重写toString方法    @Override    public String toString() {        return "Person [name=" + name + ", age=" + age + "]";    }}

学生类继承人类

class Student expents Person{    public Student() {    }    public Student(String name, int age) {        super(name, age);       }    // 重写equals方法 原来的是地址的比较 满足不了要求    // 重写用来比较学生的名字和年龄    @Override    public boolean equals(Object obj){        // 两个学生的比较 s1和s2        // this.name(本类中的名字)和obj.name(传进来的参数的名字)比较        // 传进来的参数需要进行向下转型 才可以调用getName        Student s2 = (Student)obj;        // this.getName(因为对象.方法名)是字符串        // 所以 这个equals方法 是字符串的方法        return this.getName().equals(s2.getName())&&               this.getAge() == s2.getAge();    }}

结果为:
这里写图片描述
2.LinkedList
①.测试LinkedList的方法

public static void fun1() {    LinkedList linkedList = new LinkedList();    linkedList.add("a");    linkedList.add("b");    linkedList.add("c");    // 从集合头和集合尾添加元素    linkedList.addFirst("d");    linkedList.addLast("e");    System.out.println("1." + linkedList);    // 获取头元素和尾元素    System.out.println("2." + linkedList.getFirst());    System.out.println("3." + linkedList.getLast());    System.out.println("4." + linkedList.get(1));}

结果为:
这里写图片描述
②.使用LinkedList模拟栈的入栈与出栈
入栈相当于添加,出栈相当于删除
栈结构就是先进后出 – 先进栈的最后出栈,当main函数出栈,程序结束

Linked linked = new LinkedList();linkedlist.addLast("a");linkedList.addLast("b");linkedList.addLast("c");linkedList.addLast("d");    while(!linkedlist.isEmpty){        System.out.println(linkedlist.removeLast());    }

结果为:
这里写图片描述

原创粉丝点击