黑马程序员技术交流社区

标题: 【石家庄校区】10期 JavaSE(二),day03-List、Set、数据结构、Co... [打印本页]

作者: 谁用了我的名字    时间: 2018-9-17 21:57
标题: 【石家庄校区】10期 JavaSE(二),day03-List、Set、数据结构、Co...
就业班JavaSE第二阶段第3天


day03 【List、Set、数据结构、Collections】


--数据结构
        数据存储的常用数据结构有:
                栈:        先进后出,它是受限的线性表,其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作
                队列:        先进先出,也是运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除
                数组:
                        查询快--数组的地址是连续的,我们通过数组的首地址可以找到数组,通过数组的索引可以快速查找某一个元素
                        增删慢--数组的长度是固定的,我们想要增加/删除一个元素,必须创建一个新数组,把原数组的数据复制过来
                链表:
                        查询慢--链表中的地址不是连续的,每次查询元素,都必须从头开始查询
                        增删快--链表结构,增/删一个元素,对链表的整体结构没有影响,所以增删快
                红黑树:
                        查找速度特别快
       
--List集合
        Lsit接口继承自Collection接口
        特点:
                有序的集合,存储元素和取出元素的顺序是一致的
                有索引,包含了一些带索引的方法
                允许存储重复的元素
        List接口中带索引的方法(特有)
                public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
                public E get(int index) :返回集合中指定位置的元素。
                public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
                public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
        注意:
                操作索引的时候,一定要防止索引越界异常
                IndexOutOfBoundsException:索引越界异常,集合会报
                ArrayIndexOutOfBoundsException:数组索引越界异常
                StringIndexOutOfBoundsException:字符串索引越界异常
               
                package com.itheima.test01;


                import java.util.ArrayList;
                import java.util.Iterator;
                import java.util.List;


                public class ListTest01 {
                        public static void main(String[] args) {
                                //创建List集合
                                List<String> list = new ArrayList<>();
                                //public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
                                list.add("a");
                                list.add("b");
                                list.add("c");
                                list.add("d");
                                System.out.println(list);//[a, b, c, d],打印的不是地址值,证明List接口重写了toString()方法


                                //public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
                                String set = list.set(2, "ithiema");
                                System.out.println("替换之前的元素:" + set);//替换之前的元素:c
                                System.out.println("在指定位置添加元素后的集合:" + list);//在指定位置添加元素后的集合:[a, b, ithiema, d]


                                //public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
                                String remove = list.remove(3);
                                System.out.println("移除的元素是:" + remove);//移除的元素是:d
                                System.out.println("移除指定元素后的集合:" + list);//移除指定元素后的集合:[a, b, ithiema]


                                //public E get(int index) :返回集合中指定位置的元素。
                                //遍历集合获取集合中的元素
                                //普通for循环
                                for (int i = 0; i < list.size(); i++) {
                                        System.out.println(list.get(i));
                                }


                                //迭代器获取集合元素
                                //创建迭代器对象
                                Iterator<String> it = list.iterator();
                                while (it.hasNext()) {
                                        System.out.println(it.next());
                                }


                                //增强for循环获取集合元素
                                for (String s : list) {
                                        System.out.println(s);
                                }


                                //数组越界异常:
                                for (int i = 0; i < list.size(); i++) {
                                        System.out.println(list.get(5));//IndexOutOfBoundsException: Index 5 out-of-bounds for length 3
                                }
                        }
                }
       
       
        LinkedList集合特点:
                是List集合的子类,list接口的方法都可以使用,底层是一个链表结构:查询慢,增删快
                里面包含了大量操作收尾元素的方法
                注意:       
                        使用LinkdeList集合特有的方法,不能使用多态
                特有方法:
                        public void addFirst(E e) :将指定元素插入此列表的开头。
                        public void addLast(E e) :将指定元素添加到此列表的结尾。
                        public E getFirst() :返回此列表的第一个元素。
                        public E getLast() :返回此列表的最后一个元素。
                        public E removeFirst() :移除并返回此列表的第一个元素。
                        public E removeLast() :移除并返回此列表的最后一个元素。
                        public E pop() :从此列表所表示的堆栈处弹出一个元素。
                        public void push(E e) :将元素推入此列表所表示的堆栈。
                        public boolean isEmpty() :如果列表不包含元素,则返回true


--Set集合
        Set接口继承自Collection接口,无序的集合
        特点:       
                不允许存储重复的元素
                没有索引,没有带索引的方法,也不能使用普通for循环遍历
                        可以使用迭代器和增强for遍历取出元素
               
        HashSet集合:
                是Set接口的一个实现类,是根据对象的哈希值来确定元素在集合中的位置
                特点:
                        不允许存储重复的元素
                        没有索引,没有带索引的方法,也不能使用普通for循环遍历
                        是一个无序的集合,存储元素和取出元素的顺序可能不一致
                        底层是一个哈希表结构(查询速度非常快)
                哈希值:
                        是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来的地址,不是实际数据存储的物理地址)
                        在Object类有一个方法,可以获取对象的哈希值
                                int hashCode():返回该对象的哈希码值
                                hashCode方法的源码:
                                        public native int hashCode();
                                        native:代表方法调用的是本地操作系统的方法
                                       
        HashSet集合存储数据的结构(哈希表):
                哈希表=数组+链表
                哈希表=数组+红黑树(提高查询的速度)
               
        Set集合不允许存储重复元素的原理:
                Set集合唉调用add方法的时候,会调用元素的hashCode方法和equals方法,判断元素是否重复
       
        HashSet存储自定义类型元素:
                package com.itheima.test02;


                import java.util.HashSet;
                import java.util.Iterator;


                public class HashSetTest {
                        public static void main(String[] args) {
                                //HashSet存储自定义类型数据
                                //没有重写hashCode与equals方法
                                HashSet<Person> set = new HashSet<>();
                                set.add(new Person("赵丽颖", 27));
                                set.add(new Person("赵丽颖", 27));
                                set.add(new Person("赵丽颖", 30));
                                System.out.println("没有重写hashCode与equals方法:");
                                for (Person person : set) {
                                        System.out.println(person);
                                        //所有元素全部添加了进去
                                   /* Person{name='赵丽颖', age=30}
                                        Person{name='赵丽颖', age=27}
                                        Person{name='赵丽颖', age=27}*/
                                }


                                HashSet<Person> set1 = new HashSet<>();
                                set1.add(new Person("杨幂", 37));
                                set1.add(new Person("杨幂", 37));
                                set1.add(new Person("杨幂", 40));
                                //重写了hashCode与equals方法
                                System.out.println("重写了hashCode与equals方法:");
                                Iterator<Person> it = set1.iterator();
                                while (it.hasNext()) {
                                        System.out.println(it.next());
                                        /*Person{name='杨幂', age=40}
                                        Person{name='杨幂', age=37}*/
                                }
                        }
                }


        LinkedHashSet集合:
                继承HashSet集合实现Set集合
                特点:有序的,不允许存储重复元素


--可变参数
        使用前提:
                当发放的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
        格式:定义方法时使用
                修饰符 返回值类型 方法名(数据类型...变量名){}
        原理:
                可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
                传递的参数个数,可以使0个,1,2,3,4...多个
        注意事项:
                一个方法的参数列表,只能有一个可变参数
                如果方法的参数有多个,那么可变参数必须卸载参数列表末尾
               
--Collections
        java.utils.Collections 是集合工具类,用来对集合进行操作。部分方法如下:
                public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
                public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
                public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
                public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。
               
                public class CollectionsTest01 {
                        public static void main(String[] args) {
                                //public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。
                                ArrayList<Integer> list = new ArrayList<>();
                                Collections.addAll(list,2,10,8,5,1,9);
                                System.out.println(list);
                                //public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。
                                Collections.sort(list);
                                System.out.println("排序之后的集合:"+list);//默认升序排列
                                //public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
                                Collections.shuffle(list);
                                System.out.println("打乱顺序之后的集合:"+list);//随机打乱
                        }
                }
               
        使用Comparable进行排序:
                import java.util.ArrayList;
                import java.util.Collections;


                public class ComparableTest01 {
                        public static void main(String[] args) {
                                ArrayList<Student> list = new ArrayList<>();
                                Collections.addAll(list, new Student("JAVA", 25),
                                                                                new Student("C++", 13),
                                                                                new Student("PHP", 27),
                                                                                new Student("Python", 19));
                                System.out.println("未进行排序:" + list);
                                //如果集合中存储的是自定义的数据类型,想要集合中的元素完成排序,那么必须要实现比较器Comparable接口。
                                /*
                                * public class Student implements Comparable<Student>{
                                        ...
                                        @Override
                                        public int compareTo(Student o) {
                                                return  o.age-this.age;//降序
                                                //return  this.age-o.age;//升序
                                        }
                                }
                                */
                                Collections.sort(list);
                                System.out.println(list);
                        }
                }
               
        使用Comparator进行排序:
                import java.util.ArrayList;
                import java.util.Collections;
                import java.util.Comparator;


                public class ComparatorTest {
                        public static void main(String[] args) {
                                ArrayList<Student> list = new ArrayList<>();
                                //向list集合中添加元素
                                Collections.addAll(list,new Student("Java",30),
                                                new Student("PHP",20),
                                                new Student("C++",40),
                                                new Student("Python",30));
                                //使用自定义规则对集合中的元素进行排序
                                Collections.sort(list, new Comparator<Student>() {
                                        @Override
                                        public int compare(Student o1, Student o2) {
                                                int result = o1.getAge() - o2.getAge();//升序
                                                        //return o2.getAge()-o1.getAge();//降序
                                                //如果年龄相同,则比较名字中的首字母
                                                if (o1.getAge()==o2.getAge()){
                                                        result = o1.getName().charAt(0) - o2.getName().charAt(0);
                                                }
                                                return result;
                                        }
                                });
                                System.out.println(list);
                        }
                }
               
        Comparable和Comparator区别:
                Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较规则comparaTo方法
                Comparator:相当于找一个第三方裁判,比较









欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2