List、Set、数据结构、Collections

一.数据结构:
  1.什么是数据结构:
    一种数据的存储方式
  2.常见的4+1种数据结构
    堆栈结构:
      它是只有一个开口的容器结构
      特点:
        先进后出(FILO)
      例子:弹夹,桶装可比克
    队列结构:
      它是两端都有开口的容器结构
      特点:
        先进先出(FIFO)
      例子:
        安检机
    数组结构:
      数组结构在内存中是一块连续的区域
      特点:
        对元素的查询非常快(原因:有下标)
        对元素的增加和删除非常慢
        过程:
          增加的过程:
            要添加数组的长度,创建新的数组
            进行复制 旧数组
            添加新元素
            再销毁旧数组(JVM里边有垃圾回收器)
          删除的过程:
            减少数组的长度,创建新的数组
            进行复制
            再销毁旧数组(JVM里边有垃圾回收器)
    链表结构:
      分开环链表,闭环链表
      单列表:指针域:数据域
      双列表:指针域:数据域:指针域
      链表结构中,每一个元素我们一般称为节点
      组成部分:
        数据域,指针域
      链表结构在内存是可以不连续的
      优点:
        可以提高内存的利用率
      特点:
        查询慢
        增删快
      哈希表结构:(数组结构和链表结构的组合)
        特点:
          查询快
          增删快
  红黑树结构:
    红黑树结构的查找效率非常快
二.List接口
  1.List接口的特点:
    a.有序:存储的顺序和取出的顺序是一致的(比如:保存时1 2 3 取出时1 2 3 )
    b.有索引:说明有下标(就是跟下标相关方法)
      增:add(元素),add(int index,元素)
      删:remove(元素),remove(int index);
      改:set(int index,新元素)
      查:get(int index);
    c.元素可重复:集合中可以保存两个相同的元素
  2.List接口中常用的方法以及常用子类
    增:add(元素),add(int index,元素)
    删:remove(元素),remove(int index);
    改:set(int index,新元素)
    查:get(int index);
    具体的常用实现类:
      ArrayList,LinkedList,Vector
  3.ArrayList的数据结构以及使用
    底层数据结构:数组结构(查询快,增删慢)
    特有方法:无
  4.LinkList的数据结构以及使用
    底层数据结构:链式结构(查询慢,增删快)
    特有方法:(大量和首位操作方法)
      -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();从此列表所表示的堆栈处弹出一个元素(弹出,删除元素)和removeFirst是一样的功能
      -public void push(E e);将元素推入此列表所表示的堆栈(推入,添加元素)和addFirst是一样的功能
三.Set接口
  1.Set接口的特点:
    a.无序:指的是元素存储顺序和取出顺序不一定一致(LinkedHashSet除外)
    b.索引:说明集合没有下标,只能通过迭代器(增强for循环)
    c.元素不可重复:集合中只能有一个相同的元素
  2.Set接口的常用方法以及常用子类
    特有方法:无
    常用实现类:
    HashSet,LinkedHashSet,TreeSet
  3.HashSet的数据结构以及使用
    底层数据结构:哈希表结构(查询快,增删快)
    如果哈希结构大的话:会加上红黑树结构
    所有的哈希表结构 都有一个特点:保证元素是唯一的
  4.哈希表结构的介绍(扩展)
    只有底层是哈希表结构,就能保证元素的唯一的吧!!!
    对象的哈希码值(对象的“数字指纹”)-----每一个对象都有一个哈希值
    a.java中所有的对象都有哈希码值,怎么得到:
      调用 对象名.hashcode()方法即可得到
    下面给出几个常用的哈希码的算法。
      1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
      2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。
      3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈        希码也一样。
    b.我们平时说的地址值,其实是假的!!!
      获取到对象的哈希值,给你转成16进制,骗你说这是地址值
      注意:
        java中其实是有地址值的,在对象名中,只是java打印不出地址值。
       结论:哈希表结构如何保证元素的唯一性?
          过程:
            首先比较两个元素的哈希码值
            如果哈希码值相同,再调用equals方法查看是否为true
            只有哈希码值相同,并且equals方法也返回true,才判断这两个元素是重复的,不添加。
      思考问题:
        那么不同的对象,哈希值可能相同吗?
          如果对象没有重写hashCode,那么肯定是调用Object的hashCode
          而hashCode的返回值是int(42亿种),对象有无数个,所有哈希值是有可能相同(可能性低)
          如果对象重写了hashCode,那就要看如何重写了
  5.LinkedHashSet的数据结构以及使用
    底层数据结构:链表和哈希表(数组+链表+红黑树【当元素超过8个,那么这个链表结构就会变身成红黑树】)
    特点:有序,无索引,元素不可重复

    练习:使用哈希表结构,保存自定义对象
    如果要保证自定义对象的唯一性,必须重写对象hashCode和equals

  6.可变参数
    JDK1.5出现的新特性
      可变参数:可变参数指的是参数的个数可以随便写(而不是参数类型)
    格式:
      public 返回值类型 方法名(数据类型...变量名){

      }

     例子:

 public static void main(String[] args) {
        //调用
        System.out.println(getSum(10));
        System.out.println(getSum(11, 51));
        System.out.println(getSum(102, 12, 45));
        System.out.println(getSum());

    }
    //可变参数指的是参数的个数
    public static int getSum(int...nums){
        int sum=0;
        for (int num : nums) {
            sum+=num;
        }
        return sum;
    }

   结果:

10
23
39
0

Process finished with exit code 0

   本质:
      可变参数的底层就是数组,打印时,通过遍历来打印。
    注意事项:
      一个方法只能有一个可变参数
      一个方法中如果有可变参数和正常的参数,那么可变参数必须写到最后
四.Collections
  1.Collections的介绍
    Collections是集合工具类,专门方便我们操作集合
    Arrays是数组工具类,专门方便我们操作数组
  2.常用功能方法
    -public static <T> boolean addAll (Collection<T> c,T... elements);将所有指定元素添加到指定 collection 中。

    例子:

    public static void main(String[] args) {
        //1.添加所有
        ArrayList<String> names=new ArrayList<String>();
        //添加
        Collections.addAll(names,"小苗","java","强");
//        for (String name : names) {
//            System.out.println(name);
//        }
        System.out.println(names);
        
    }

    结果:

[小苗, java, 强]

Process finished with exit code 0

    -public static void shuffle(List<?> list);打乱顺序:打乱集合顺序(只有list才可以排)
    -public static<T> void sort(List<T> list);将集合中元素按照默认规则升序排序
  3.扩展1:Comparable<T>自然排序接口
    Collections的sort对集合进行排序时,必须满足集合的泛型需要实现一个接口Comparable
    实现Comparable接口,重写方法,比较方法
      this和传入的对象进行比较
      返回值正数:代表this大
      返回值负数:代表传入的对象大
      返回值为0:代表相同
    升序:
      this减去传入的数据

  4.扩展2:Comparator<T>比较器排序接口
    Collections的sort方法,除了接收集合之外,还可以接收一个比较器Comparator接口的实现类对象
    这时候自然排序接口就起不了作用。
    Comparator接口
    创建接口的实现类对象------用匿名内部类
      new Comparator
    升序就 是1的减去2 的
  总结:两种比较方式的优劣
    第二种比较器排序比较灵活
    因为第一种比较已经写死比较规则
    第二种比较 由于比较规则由程序员自己传递,所以可以随时变换比较规则

  例子:

public class Girl implements Comparable<Girl>{
    int age;
    String name;
    public Girl(){
    }

    public Girl(int age, String name) {
        this.age = age;
        this.name = name;
    }
//重写方法比较方法
    public int compareTo(Girl o) {
        //this和o的比较
        //记住:返回值正数 代表this大
        //      返回值负数 代表o大
        //      返回值0    代表相等
        return this.age-o.age;
        //升序就是 我 减它
    }

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

  实现:

    public static void main(String[] args) {
        //排序自定义类型
        ArrayList<Girl> gg=new ArrayList<Girl>();
        //保存自定义对象
         gg.add(new Girl(12,"add"));
         gg.add(new Girl(14,"frcdc"));
         gg.add(new Girl(11,"eec"));
         gg.add(new Girl(17,"ceex"));
         //排序
//        Collections.sort(gg);//按照Comparable接口自然排序
            Collections.sort(gg, new Comparator<Girl>() {
                public int compare(Girl o1, Girl o2) {
                    //升序就是1减2
                    return o1.name.length()-o2.name.length();
                }
            });//根据比较器进行排序
        System.out.println(gg);

    }

  结果:

[Girl{age=12, name='add'}, Girl{age=11, name='eec'}, Girl{age=17, name='ceex'}, Girl{age=14, name='frcdc'}]

Process finished with exit code 0

5.排序练习(代码实现)
  创建一个学生类,存储到ArrayList集合中,
  要求按照学生的年龄升序排序,
  如果年龄相同那么按照名字的第一个字母升序排序

代码:

public class Student implements Comparable<Student>{
    int age;
    String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Student() {
    }

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

    public int compareTo(Student o) {
        return 0;
    }
}

  代码:

 public static void main(String[] args) {
        ArrayList<Student> list=new ArrayList<Student>();
        list.add(new Student(44,"af"));
        list.add(new Student(14,"fsf"));
        list.add(new Student(15,"rv"));
        list.add(new Student(16,"sef"));
        list.add(new Student(16,"ugc"));
        Collections.sort(list, new Comparator<Student>() {
            public int compare(Student o1, Student o2) {
                if(o1.age==o2.age ){
                    return o1.name.charAt(0)-o2.name.charAt(0);
                }

                return o1.age-o2.age;
            }
        });
        System.out.println(list);

    }

  结果:

[Student{age=14, name='fsf'}, Student{age=15, name='rv'}, Student{age=16, name='sef'}, Student{age=16, name='ugc'}, Student{age=44, name='af'}]

Process finished with exit code 0

面试题:
向哈希表结构的集合中,添加重复元素时,根本添加不进去,add方法的返回值是false

 

posted on 2019-01-10 14:56  杰cc  阅读(217)  评论(0)    收藏  举报