zoukankan      html  css  js  c++  java
  • java数据结构3--List

    List

    1.1 list接口的简介

    1.2 list实现子类

    ArrayList
    线程不安全,查询速度快,底层用的是数组,增删慢
    LinkedList
    线程不安全,链表结构,增删速度快,查询慢
    Vector
    线程安全,但速度慢,已被ArrayList替代

    1.3 list的遍历方法

    迭代器注意事项:
    迭代器在Collcection接口中是通用的
    迭代器的next方法返回值类型是Object,如果需要所以要记得类型转换。

    1.4练习

    1.使用ArrayList存储基本数据类型对象,并遍历
    2.使用ArrayList存储字符串对象,并遍历
    import java.util.ArrayList;
    
    /*
     * 使用ArrayList存储基本数据类型对象,并遍历
    
     */
    public class Demo1 {
    
        public static void main(String[] args) {
    //        Colletion 
    //        List
            ArrayList list = new ArrayList();
            
            list.add(10);//此处发生的是自动装箱int --> Integer 1.5
            list.add(true);//Boolean
            list.add(3.14);//Double
            list.add('a');//Character
            /*
             * 
             * 
             *     list.add(Integer.valueOf(10));
                list.add(Boolean.valueOf(true));
                list.add(Double.valueOf(3.1400000000000001D));
                list.add(Character.valueOf('a'));
             */
            for (Object object : list) {
                System.out.println(object);
            }
                
        }
    
    }
    练习1

    练习2:

    3.使用ArrayList存储自定义类型对象,并遍历
    4.使用ArrayList实现字符串的去重
    import java.util.ArrayList;
    
    /*
     * 使用ArrayList存储自定义类型对象,并遍历
     * 
     * 
     * 快速生成Getters Setters :
     *      alt + shift + s : --> Generate getters and setters
                            -->空参构造方法
                            -->带参构造方法    
     */
    
    class Student {
        private String name;
        private int 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;
        }
    
        public Student() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
    
        
    }
    
    public class Demo3 {
    
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 创建自定义对象
            Person s1 = new Person("张三", 15);
            Person s2 = new Person("李四", 25);
            Person s3 = new Person("王五", 20);
    
            // 添加到集合
            list.add(s1);
            list.add(s2);
            list.add(s3);
            //添加匿名对象
            list.add(new Person("tom", 16));
            
            for (Object obj : list) {
                Person s = (Person) obj;//元素类型确切是Student才能强转成功
    //            System.out.println(s.getName() + "--" + s.getAge());
    //            System.out.println(s.toString());
                System.out.println(s);//间接调用toString方法
            }
        }
    
    }
    练习3
    import java.util.ArrayList;
    
    /*
     * 使用ArrayList实现字符串的去重
     * 
     * 思路:
     *     创建一个新的集合.
     *     把原集合中的元素取出,在新集合中进行判断.如果包含,就不添加,如果不包含,就添加.
     *     遍历完,新集合中就是去重之后的结果.
     * 
     * 不创建新集合实现去重:
     * 思路:从前往后比较,注意删除元素后,后面的元素会向前移位
     *     
     * 
     */
    public class Demo4 {
    
        public static void main(String[] args) {
            /*
            ArrayList list = new ArrayList();
            list.add("abc");
            list.add("abc");
            list.add("abc2");
            list.add("abc2");
            list.add("world");
    
            //创建一个新集合
            ArrayList list2 = new ArrayList();
            for (Object obj : list) {
                //contains
                if(!list2.contains(obj)){
                    list2.add(obj);
                }
            }
            
            //打印新集合内容
            System.out.println(list2);//调用toString方法 
            */
            ArrayList list = new ArrayList();
            list.add("abc");
            list.add("abc");
            list.add("abc");
            list.add("abc2");
            list.add("abc2");
            list.add("abc2");
            list.add("abc2");
            list.add("abc3");
            list.add("abc3");
            list.add("abc3");
            list.add("abc3");
            list.add("abc3");
            
            //从前往后比较,注意删除元素后,后面的元素会向前移位
            /*
            for(int i = 0;i<list.size() - 1;i++){
                for(int j = i + 1;j<list.size();j++){
                    if(list.get(i).equals(list.get(j))){
                        list.remove(j);
                        j--;
                    }
                }
            }
            */
            
            //2.从后往前比较
            for(int i = 0;i<list.size();i++){
                for(int j = list.size() - 1;j>i;j--){
                    if(list.get(i).equals(list.get(j))){
                        list.remove(j);
                    }
                }
            }
            System.out.println(list);
        }
    
    }
    练习4
    import java.util.ArrayList;
    
    /*
     *重写equals方法原则
     *    1.先进行非空判断
     *    2.转换成同类型
     *    3.对所有的成员变量进行比较,所有的成员变量都相同的情况下才是相同的对象
     *
     * 
     */
    
    class Person {
        private String name;
        private int 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;
        }
    
        public Person() {
            super();
        }
    
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
    
        /*
         * 重写equals方法,告诉虚拟机什么情况下两个对象才是相同的对象
         *  步骤:非空判断 --> 类型转换 --> 成员变量比较
         */
        /*
        @Override
        public boolean equals(Object obj) {
    //        return true;
            
            //所有的成员变量都相同的情况下,两个对象才是相等的.
            if(obj == null){
                return false;
            }
            //把传入的参数进行类型转换,同类才能比
            Person p = (Person)obj;
            
            int age2 = p.getAge();
            String name2 = p.getName();
            if(age2 == age && name.equals(name2)){
                return true;
            }
            //出现任何一个成员变量不同,都不能称为相同的对象.
            return false;
            
        }
        */
        
        
        
    }
    
    public class Demo5 {
    
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 创建自定义对象
            Person p1 = new Person("tom",15);
            Person p2 = new Person("toms",16);
    
            list.add(p1);
            list.add(p2);
    
            //创建新集合
            ArrayList list2 = new ArrayList();
            for (Object obj : list) {
                if(!list2.contains(obj)){//底层调用的是equals方法.根据返回值判断是否能添加成功
                    list2.add(obj);
                }
            }
            
            for (Object object : list2) {
                Person p = (Person)object;
                System.out.println(p.getName() +"--"+ p.getAge());
            }
            
        }
    
    }
    练习3

    note:技巧

    1.5 contains方法

    思路:创建新集合,从原集合里拿出元素放入新集合,放入的同时做判断
    使用的是contains方法

    通过查看contains方法的源码,实际上调用的是要添加元素的equals方法
    即:如果要添加元素对已经存在的元素调用equals方法,返回true表明已经存在,返回false表明不存在.

    默认equals是继承自Object类的,只是简单的比较地址
    自定义类要重写equals方法,告知虚拟机到底什么情况下对象才是”相等”的。

    import java.util.ArrayList;
    
    /*
     *重写equals方法原则
     *    1.先进行非空判断
     *    2.转换成同类型
     *    3.对所有的成员变量进行比较,所有的成员变量都相同的情况下才是相同的对象
     *
     * 
     */
    
    class Person {
        private String name;
        private int 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;
        }
    
        public Person() {
            super();
        }
    
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
    
        /*
         * 重写equals方法,告诉虚拟机什么情况下两个对象才是相同的对象
         *  步骤:非空判断 --> 类型转换 --> 成员变量比较
         */
        /*
        @Override
        public boolean equals(Object obj) {
    //        return true;
            
            //所有的成员变量都相同的情况下,两个对象才是相等的.
            if(obj == null){
                return false;
            }
            //把传入的参数进行类型转换,同类才能比
            Person p = (Person)obj;
            
            int age2 = p.getAge();
            String name2 = p.getName();
            if(age2 == age && name.equals(name2)){
                return true;
            }
            //出现任何一个成员变量不同,都不能称为相同的对象.
            return false;
            
        }
        */
        
        
        
    }
    
    public class Demo5 {
    
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 创建自定义对象
            Person p1 = new Person("tom",15);
            Person p2 = new Person("toms",16);
    
            list.add(p1);
            list.add(p2);
    
            //创建新集合
            ArrayList list2 = new ArrayList();
            for (Object obj : list) {
                if(!list2.contains(obj)){//底层调用的是equals方法.根据返回值判断是否能添加成功
                    list2.add(obj);
                }
            }
            
            for (Object object : list2) {
                Person p = (Person)object;
                System.out.println(p.getName() +"--"+ p.getAge());
            }
            
        }
    
    }
    练习3

    1.6 并发修改异常

    在使用迭代器和增强for循环遍历ArrayList的时候,使用集合本身的方法修改了集合,将导致并发修改异常:ConcurrentModificationException (两个不要交叉使用)

    foreach本质上:是使用了迭代器

    1.使用迭代器遍历,使用迭代器删除(修改)元素
    2.使用集合本身遍历且非foreach,使用集合本身方法删除(修改)元素

    如何添加元素:
    查看Iterator接口的方法,没有添加元素的方法
    但是它的子接口ListIterator有添加元素的方法

    1.7 Vector类

    Vector类是1.0就已经有的,在1.2被整合到集合框架中
    其中的大部分方法都和ArrayList相同,但它是线程安全的,所以效率要低。

    import java.util.Enumeration;
    import java.util.Vector;
    /*
     * 
     * jdk升级的原因:
     *     1.提供新方法.
     *     2.简化书写.
     */
    public class VectorDemo {
    
        public static void main(String[] args) {
            Vector v = new Vector<>();
            
            v.addElement("hello");
            v.addElement("world");
            
            System.out.println(v.size());
            
            v.removeElement("hello");
            System.out.println(v.size());
            
            Enumeration en = v.elements();
            while(en.hasMoreElements()){
                Object obj = en.nextElement();
                System.out.println(obj);
            }
        }
    
    }

    1.8LinkedList类

    LinkedList 类底层使用的是链表结构保存数据
    LinkedList底层使用的是链表,但是自己维护了一个索引,
    所以也提供了get(int index)的方法来通过索引获取元素
    但此方法的效率很低,一般不使用。
    绝大多数方法和ArrayList相同,只不过多了一些对首尾元素操作的方法

    addFirst()
    addLast()
    remove()

     

    练习:
    使用LinkedList类模拟栈结构的集合.
    注意是模拟栈结构,不是直接使用LinkedList,即:有一个集合,其中的元素是先进后出.
    /*
     * 练习:
        使用LinkedList类模拟栈结构的集合.(FILO,LIFO)
        注意是模拟栈结构,不是直接使用LinkedList,即:有一个集合,其中的元素是先进后出.
    
        自己设计一个类:
            最基本的方法:存, 取.
            在此基础之上体现栈的特点:FILO
            
        public class MyStack{
            //成员位置包含一个LinkedList
            LinkedList list = new LinkedList();
            
            //add:真正操作的是list
             
            //get:真正操作的是list
        }
    
     */
    
    import java.util.LinkedList;
    
    class MyStack{
        //在成员位置保持一个LinkedList的引用
        LinkedList list = new LinkedList();
        
        //add
        public void add(Object obj){
            list.addFirst(obj);
        }
        
        //get
        public Object get(){
            return list.pop();
        }
        
        //提供判断是否含有元素方法
        public boolean isEmpty(){
            return list.isEmpty();
        }
    }
    
    
    public class LinkedListDemo2 {
    
        public static void main(String[] args) {
            MyStack ms = new MyStack();
            ms.add("hello");
            ms.add("world");
            ms.add("java");
            ms.add("hadoop");
            ms.add("mysql");
            
            //
    //        System.out.println(ms.get());
    //        System.out.println(ms.get());
    //        System.out.println(ms.get());
    //        System.out.println(ms.get());
    //        System.out.println(ms.get());
    //        System.out.println(ms.get());
            
            while(!ms.isEmpty()){
                System.out.println(ms.get());
            }
        }
    
    }
    模拟栈结构
  • 相关阅读:
    [root@192 ~]# ls /etc/sysconfig/network-scripts
    解决unknown import path "golang.org/x/sys/unix": unrecognized import path "golang.org/x/sys"
    Centos 修改IP地址、网关、DNS
    Centos7 下安装golang
    yum国内镜像配置
    grep -R --include=*.log warning /var/log
    第五章 单例模式(待续)
    第四章 工厂模式(待续)
    第三章 装饰者模式(待续)
    第二章 观察者模式(待续)
  • 原文地址:https://www.cnblogs.com/wqbin/p/11191374.html
Copyright © 2011-2022 走看看