LinkedList集合,Set接口,可变参数,Collections集合工具类

LinkedList集合:

    java.util.LinkedList  集合数据存储的结构底层是一个链表结构,是一个双向链表结构,方便元素的添加和删除。开发中对链表集合的元素大量的都是采用首尾结点操作(添加和删除):常用的API方法如下:

  • 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.
  • public static void demo1() {
            //        public void addFirst(E e):将指定元素插入到首节点位置
            //        public void addLast(E e):将指定的元素插入到尾节点的位置上
            //        public void push(E e):将元素推入到此列表所表示的堆栈当中(首元素)
            LinkedList<String> strings = new LinkedList<>();
            strings.addFirst("a");
            strings.addFirst("b");
            strings.addFirst("c");
            System.out.println(strings);//[c, b, a]
            strings.addFirst("d");
            System.out.println(strings);//[d, c, b, a]
            strings.addLast("g");
            System.out.println(strings);//[d, c, b, a]
            strings.push("t");
            System.out.println(strings);//[t, d, c, b, a, g]
        }
        public  static void demo2(){
            //public  E removeFirst():删除首节点元素
            //public  E removeLast():删除尾节点元素
            //public  E pop():从此列表所表示的堆栈中弹出一个元素(首元素)
            LinkedList<String> strings = new LinkedList<>();
            strings.addFirst("a");
            strings.addFirst("b");
            strings.addFirst("c");
            System.out.println(strings);//[c, b, a]
            System.out.println(strings.getFirst());//c
            System.out.println(strings.getLast());//a
            System.out.println(strings.pop());//c
            System.out.println(strings.getFirst());//b
            //strings.clear();
            // 清空集合当中的元素,再次获取直接抛出java.util.NoSuchElementException
            // java.util.NoSuchElementException
        }
        public  static  void demo3(){
            //public  E removeFirst():删除首节点元素
            //public  E removeLast():删除尾节点元素
            //public boolean isEmpty():如果此列表为空返回true.
            LinkedList<String> strings = new LinkedList<>();
            strings.addFirst("a");
            strings.addFirst("b");
            strings.addFirst("c");
            System.out.println(strings);//[c, b, a]
            System.out.println(strings.removeFirst());//c
            System.out.println(strings.removeLast());//a
            System.out.println(strings);//b
            System.out.println(strings.isEmpty());//false
            System.out.println(strings.removeFirst());//b
            //System.out.println(strings.removeLast());//a
            System.out.println(strings.isEmpty());//true
        }
    

     

Linkedlist集合的特点:

  1.      底层是链表结构,增删快,查询慢
  2.      里面包含了大量的首尾节点的操作
  3.      允许所有元素(包括 null)
  4.      此实现不是同步的。如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须保持外部同步
  5.      元素是有序的。

    LinkedList是List的子类,List当中的方法LinkedList都是可以使用的。我们只了解LinkedList独有的方法,

    在开发当中,LinkedList集合也可以作为堆栈、队列结构使用(了解)

      

Set接口:

   java.util.Set接口和 java.util.List接口是一样的,都是继承自Collection接口,它与Collection接口中的方法基本一样,没有对Collection接口进行功能上的扩展,只是比Collection接口更加严格,与List接口不同的是,Set接口中的元素是无序的,并且都是以某种规则保证存入的元素不重复。

Set接口有很多个子类,我们主要介绍两个重要的子类:java.util.HashSet和java.util.LinkedHashSet

Set接口特点:

     1.不允许存储重复的元素

     2.没有索引,没有带索引的方法,也不能使用普通的for循环进行遍历,可用迭代器和增强for循环进行元素的获得。

   HahSet集合的特点:

     1.不允许存储重复的元素

     2.没有索引,没有带索引的方法,也不能使用普通的for循环进行遍历

     3.是一个无序的集合,存储的元素顺序和取出元素的顺序可能不一致

     4.底层是一个哈希表结构(查询速度非常的快)java.util.HashMap支持的。

     5.根据对象的哈希值来确定元素在集合当中的存储位置,因此它具有良好的存取和查找的性能。保证元素唯一性的方式依赖于hashCode和equals

哈希值:

       是十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)。是由Object类中有一个方法,可以获取对象的哈希值int   hashCode()返回对象的哈希码值。

       查看源码:public native int hashCode();

        native:代表的是该方法调用的是本地操作系统中的方法。

哈希表:

   JDK1.8之前:哈希表=数组+链表  即使用链表处理哈希冲突,同一哈希值的链表都存储在一个链表里,但是当           位于一个链中的元素较多时,即hash值相等的元素较多时,通过key值依次查找的效率很低下。

   JDK1.8之后:哈希表=数组+链表

                          哈希表=数组+红黑树;

                     如果链表的长度超过了8位,那么就会把链表结构转换成红黑树结构。这样的好处是大大减少了查找的时间   

JDK1.8之后引入的红黑树结构大大优化了HashMap的性能,那么对于我们来讲保证HashCode元素唯一不重复,其实是根据对象的hashCode和equals方法来决定的,如果我们往集合当中存储的是自定义的对象,需要保证对象的唯一性,就必须重写HashCode和equals方法,来自定义当前对象的比较方式。

HashSet存储自定义类型的元素

      一般需要重写对象当中的hashCode和equals方法。建立自己的比较方式。才能保证HashSet集合中元素的唯一性。

@Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        // 向下转型 类型判断
        if (o instanceof Student) {
            Student student = (Student)o;
            // 同名同年龄的人为同一个人 true
            return student.getName().equals(name) && student.getAge() == age;
        }
        return false;
    }

    @Override
    public int hashCode(){
         // 使用Objects类中的hash方法
        return Objects.hash(name,age);
    }

LinkedHashSet集合:

        hashset保证元素的唯一,可是存进去的元素是没有顺序的,那么如何保证存进去的元素是有序的?

在java.util.HashSet类的下面还有一个子类java.util.LinkedHashSet,它是链表和哈希表的组合一个数据存储结构。

 LinkedHashSet底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表,用来记录元素的存储的顺序,来保证元素的有序。

        具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,
        后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,
        即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。

  public static void main(String[] args) {
        // 构建一个HashSet集合对象
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("www");
        hashSet.add("zhiyou100");
        hashSet.add("com");
        hashSet.add("abc");
        hashSet.add("abc");
        System.out.println(hashSet);// [com, abc, www, zhiyou100]  无序的 不重复的

        // 构建一个LinkedHashSet集合对象
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("www");
        linkedHashSet.add("zhiyou100");
        linkedHashSet.add("com");
        linkedHashSet.add("abc");
        linkedHashSet.add("abc");
        linkedHashSet.add("java");
        linkedHashSet.add("python");
        // [www, zhiyou100, com, abc, java, python]
        System.out.println(linkedHashSet);// [www, zhiyou100, com, abc] 有序的,不重复的


    }

可变参数:

       在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数的数据类型一致,那么我们可以简化成如下格式:

      

修饰符  返回值类型  方法名(参数类型...形参名){

    //...

}

其实上面的格式完全等价于:

修饰符  返回值类型  方法名(参数类型[]...参数名){

    //...

}

        只是后面的写法,在方法调用的时候,必须传递一个数组类型,而前者可以直接传递参数数据。

  JDK1.5之后,出现的这种简化操作。”...“用在参数上,我们称之为可变参数。

 可变参数的原理:
            可变参数底层是定义了一个数组,根据传递参数的个数不同,会创建不同长度的数组,来存储这些参数
            传递的参数个数,可以是0个(不传递),1,2,...多个

 同样是代表数组 ,但是在方法上调用这个带有可变参数时,不用创建数组,而是直接将数组当中的元素作为实     际参数进行传递,其实编译生成的class文件,本质是将这些元素封装都数组当中。再进行数据传递,这些动作都在编译生成.class文件的时候,自动完成了。

   public static void add(int... arr) {
        //System.out.println(arr);// [I@1b6d3586 底层就是一个数组
        //System.out.println(arr.length);//0
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println(sum); // 30
    /*
        可变参数的终极写法 不建议用
int[] 无法转型为 Object[], 因而被当作一个单纯的数组对象 ; Integer[] 可以转型为 Object[], 可以作为一个对象数组。
     */
    //public static void methodFinal(Object ... obj){}
    }
可变参数的注意事项:
        1. 一个方法的参数列表,只能有一个可变参数
        2. 如果方法的参数有多个,类型不止一种,那么可变参数必须写在参数列表的末尾位置
        3.调用一个被重载的方法时,如果此调用既能够和固定参数的重载方法匹配,也能够与可变长参数的重载方法匹配,则选择固定参数的方法:

      

Collections集合工具类:

       常用功能:

      java.util.Collections是集合工具类,用来操作集合对象中的元素,方法如下

public static <T> boolean addAll(Collection<? super T> c, T... elements)

                   将所有指定元素添加到指定 collection 中。
public static <T> void shuffle(List<?> list)
           打乱集合中的元素顺序
 
/*

        public static <T> boolean addAll(Collection<? super T> c,T... elements):往集合中一次性添加多个元素。
        public static <T> void shuffle(List<?> list) 打乱集合中的元素顺序。
 */
 ArrayList<String> strs = new ArrayList<>();
        // 往集合当中存储元素
       /* strs.add("abc");
        strs.add("小孙");
        strs.add("小刘");
        strs.add("小赵");*/

        // 使用一下Collections集合工具类中的addAll()
        // 所有通用的 Collection 实现类(通常通过它的一个子接口间接实现 Collection)
        Collections.addAll(strs, "abc","小孙","小刘","小赵","a",new String());
        System.out.println(strs);// [abc, 小孙, 小刘, 小赵]
        System.out.println("====================");

        // 打乱顺序 public static <T> void shuffle(List<?> list)
        Collections.shuffle(strs);
        System.out.println(strs);// [小刘, 123, 小赵, a, 小孙, abc]
 
public static <T> void sort(List<T> list)
  根据元素的自然顺序 对指定列表按升序进行排序。

 

public static  void  sort(List<T> list, Comparator<? super T> c)

          将集合中的元素按照指定的规则进行排序。
/*

    public static <T> void sort(List<T> list):将集合中的元素按照默认规则排序。
    public static <T> void sort(List<T> list,Comparator<? super T> c)`:将集合中的元素按照指定的规则进行排序。

 */
public class Demo02Collections {

    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(123);
        list01.add(127);
        list01.add(125);
        list01.add(126);
        System.out.println(list01);// [123, 127, 125, 126]
        System.out.println("==============================");

        // 使用集合工具类Collections中的sort方法
        Collections.sort(list01);
        System.out.println(list01);// [123, 125, 126, 127]
        System.out.println("==============================");

        ArrayList<String> list02 = new ArrayList<>();
        Collections.addAll(list02, "a","c","ab","c","d","abc","ac","ba","abcd");
        System.out.println(list02);// [a, c, ab, c, d]

        Collections.sort(list02);
        System.out.println(list02);
        System.out.println("---------------------------------------");

        ArrayList<Student> list03 = new ArrayList<>();
        list03.add(new Student("小孙", 20));
        list03.add(new Student("小王", 21));
        list03.add(new Student("小赵", 18));
        list03.add(new Student("小周", 15));
        System.out.println(list03);
        Collections.sort(list03);
        System.out.println(list03);
        //Comparator
  // 重写排序规则
    @Override
    public int compareTo(Student o) {
        // return 0:代表的是两个元素相同
        // 自定义排序规则:按照年龄进行排序
        // this参数,o参数
        // this.getAge() - o.getAge()// 升序排序
        // o.getAge() - this.getAge() 降序排序
        return o.getAge() - this.getAge();// 降序排序
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值