集合的框架(之二)

List接口

特点:1. 元素有序,并且可以重复。2. 两个实现类:ArrayList和LinkedList      ArrayList:动态数组+各种方法      LinkedList: 双向链表+各种方法    对于随机访问来说, ArrayList要高于LinkedList 。对于频繁的插入和删除来说, LinkedList要高于ArrayList.基于List接口,两个实现类的方法基本一致。


public class ListDemo01 {
    public static void main(String[] args) {
        //创建一个ArrayList集合对象
        List<String> names = new ArrayList<>();
        //创建一个LinkedList集合对象
        List<String> adds = new LinkedList<>();

        /**
         * 添加元素:
         * boolean add(E e)  : 添加元素, 默认添加到集合尾部
         * void add(int index, E  element): 插入元素,下标范围 [0,size()]
         * boolean addAll(Collection  c )
         * boolean addAll(int index, Collection c)
         */
        names.add("michael");
        names.add(1,"bob");
        System.out.println(names);

        //地址集合添加两个元素
        adds.add("beijing");
        adds.add("shanghai");

        //将地址集合添加到名字集合中
//        names.addAll(adds);
//        System.out.println(names);

        //将地址集合添加到names集合中的两个元素中间
        names.addAll(1,adds);
        System.out.println(names);

        /**
         * E get(int index):  获取指定索引处的元素
         */
        String ele = adds.get(1);
        System.out.println("ele:"+ele);

        /**
         * 查找元素:
         * int indexOf(Object obj): 返回指定元素的第一个下标,如果没有返回-1.
         * int lastIndexOf(Object obj): 返回指定元素的最后一个下标,如果没有返回-1.
         */
        int index = names.indexOf("bob");
        System.out.println("index:"+index);
        index = names.lastIndexOf("john");
        System.out.println("index:"+index);

        /**
         * boolean remove(Object obj):
         * E remove(int index)
         */
        boolean f = names.remove("lucy");
        System.out.println("f:"+f);

        String address = adds.remove(0);
        System.out.println("address:"+address);
        System.out.println(adds);

        /**
         * E  set(int index,E e): 将指定位置上的元素替换成形参e
         */
        System.out.println("显示:"+names);

        String add1 = names.set(2, "深圳");
        System.out.println("add1:"+add1);

        System.out.println("names:"+names); //[michael, beijing, 深圳, bob]
        String add2 = names.set(0,names.set(1,"沈阳"));
        System.out.println("add2:"+add2);// michael
        System.out.println("names:"+names);// [beijing, 沈阳, 深圳, bob]

        /**
         * List subList(int fromIndex,int endIndex):
         * 用于截取子集,包前不包后
         */
        List<Integer> nums = new ArrayList<>();
        for (int i = 1; i < 11; i++) {
            nums.add(i);
        }
        System.out.println(nums);//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        List<Integer> sub = nums.subList(3, 7);
        System.out.println(sub);

        //对子集里的每一个元素扩大10倍。
        for (int i = 0; i < sub.size(); i++) {
            //取出元素*10,然后替换掉原有的元素
//            int r = nums.get(i)*10;
//            nums.set(i,r);
            sub.set(i,sub.get(i)*10);
        }
        System.out.println(sub);
        System.out.println(nums);

        new LinkedList<>(sub);
    }
}

Queue队列

也是Collection接口的子接口,用来描述一种先进先出(First Input First Output)的数据存储结构。可以理解为是一种特殊的线性表,只能从一头进入,另一头出来,对应的方法
- boolean offer(E e):  从队列的尾部进入
- E poll():    从队列的头部出来
- E peek():    查看头部的元素
public class QueueDemo01 {
    public static void main(String[] args) {
        //创建一个名字队列
        Queue<String> names = new LinkedList<>();
        //调用offer方法,入队
        names.offer("michael");
        names.offer("张三");
        names.offer("李四");
        //查看队列的样子
        System.out.println(names);
        //查看队列的头部对象
        String head = names.peek();
        System.out.println(head);

        //让头部元素出队
        while (names.peek() != null) {
            //如果想要移除头部元素,最后先查看是否有头部元素,如果有再移除。
            String oldHead = names.poll();
            System.out.println(oldHead);
            System.out.println(names);
        }
    }
}

Deque接口

双端队列:  即从队列的两头都可以入队和出队。 Deque接口,实现了双端队列的存储结构, 它是Queue的子接口。
对应的实现类,还是LinkedList();
提供的方法:
offerFirst
offerLast
pollFirst
pollLast
public class QueueDemo02 {
    public static void main(String[] args) {
        //创建一个双端队列
        Deque<String> names = new LinkedList<>();
        //添加第一个元素
        names.offer("小明");
        //第二个元素从队列的头部进入
        names.offerFirst("小红");
        //第三元素从队列的尾部进入 offer()  offerLast()
        names.offerLast("小芳");
        System.out.println(names);

        //移除元素
        //移除队列的头部  poll()  pollFirst()
        String head = names.poll();
        System.out.println("head:" +  head);
        //移除队列的尾部
        String tail = names.pollLast();
        System.out.println("tail:" +  tail);
        System.out.println(names);
    }
}
使用Deque来模拟栈的存储结构:栈:  First Input  Last Output   简称FILO
public class QueueDemo03 {
    public static void main(String[] args) {
        //创建一个存储结构
        Deque<String> stack = new LinkedList<>();

        //从栈的出口进入, 对应的方法push, 表示将元素推进去
        stack.push("michael"); //推入到栈的底部
        stack.push("lucy");    //推入,在最底层的上一层
        stack.push("lily");
        stack.push("tom");
        System.out.println(stack);

        //出栈(弹出): 对应的方法pop()  将元素弹出栈结构
        while (stack.size() > 0) {
            String el = stack.pop();
            System.out.println(el);
        }
    }
}

Set接口

是Collection的子接口。
设计初衷:用来存储不重复的元素,元素的顺序是无序的(取出的顺序和存入的顺序无关) (一旦存入,在存储结构里的顺序就固定了。和存入的先后顺序无关)
set接口里的方法都是Collection接口的方法HashSet:  是实现了Set接口的最最经典的子类型
底层的存储方式使用的是Hash算法(哈希表)

public class SetDemo01 {
    public static void main(String[] args) {
        //创建一个Set接口的对象
        Set<String> names = new HashSet<>();
        //存入michael, lucy, john, tom
        names.add("michael");
        names.add("lucy");
        names.add("john");
        names.add("tom");
        System.out.println("names: " + names);
        System.out.println("names: " + names);
        /**
         * 打印一下四个元素的hash值
         */
        System.out.println("micheal".hashCode()%16);
        System.out.println("tom".hashCode()%16);
        System.out.println("john".hashCode()%16);
        System.out.println("lucy".hashCode()%16);
//        `%16` 用于将 hash 值除以 16,并取余数。


        names.add("michael");

        System.out.println(names);
        System.out.println(names.size());
    }
}
添加元素 michael,
因为数据结构中已经存在michael,所以新的michal是添加不进来的。
去重原理:
先计算要添加的元素的hash值,然后确定哈希表中该值的位置上是否存在元素
如果不存在,可以添加,如果存在,就需要调用equals进行比较
如果equals返回true,说明不能再存入了。
如果equals返回false,说明可以存入。
注意:每个hash值对应的位置都维护了一个单向链表。可以进行存储hash值相同
equals不同的元素。

LinkedHashSet

是 HashSet 的子类
- LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
- LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。
- LinkedHashSet 不允许集合元素重复
public class SetDemo03 {
    public static void main(String[] args) {
        Set<String> set = new LinkedHashSet<>();
        set.add("a");
        set.add("b");
        set.add("c");
        set.add("bob");
        set.add("c"); //重复的,不能添加成功
        System.out.println(set);

        //使用迭代器遍历
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

TreeSet

1. TreeSet 是SortedSet接口的实现类。
2. TreeSet集合的元素是有序的,即内部维护一个二叉树算法的排序方式
3. TreeSet集合里的元素也不能重复
4. TreeSet默认排序是升序方式,如果想要改变默认的排序方式,可以自定义一个比较器,传入构造器中
回顾: LinkedHashSet,使用链表维护向集合中插入元素时的顺序
public class SetDemo04 {
    public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("a");
        set.add("h");
        set.add("b");
        set.add("f");
        set.add("d");
        set.add("bob");
        set.add("bab");
        System.out.println(set);
        Comparator c1 = new Comparator<Integer>(){
            public int compare(Integer o1 ,Integer o2){
                return o2-o1;
}
};
    Set<Integer> nums = new TreeSet<>(c1);
    nums.add(10);
    nums.add(1);
    nums.add(20);
    nums.add(2);
    System.out.println(nums);
    }
}
Sort排序
1. 不管是在数组中,还是在集合中。
要求元素必须是Comparable的子类型,因此底层需要调用Comparable的
compareTo方法。
所以,自定义的类,如果想要排序,那么必须实现Comparable接口,以及重写
compareTo方法
2. 在上述的基础之上,如果想要重新指定排序方式,不应该修改compareTo方法里的逻辑
而是应该使用Comparator比较器接口,来定义一个新的比较规则。调用集合或者数组的
相关重载方法,可以传入一个比较器的这样的方法,进行新的排序。
集合工具类:Collections  。数组工具类:Arrays
 1. 集合工具类和数组工具类一样,都提供了很多常用的方法,来操作集合对象。
- void sort(List<E> list) : 对集合元素进行升序排序。
- void sort(List<E> list,Comparator<E> c): 可以使用比较器来重新定义比较规则
public class SortDemo02 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++) {
            list.add((int)(Math.random() * 100));
        }
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    Compartor c1 = new Comparator<Integer>(){
        public int compare(Integer o1,Integer o2){
            return o2-o1;
};
    Collections.sort(list,c1);
    System.out.println(list);`

}

集合工具类其他方法演示:

public class CollectionsDemo {
    public static void main(String[] args) {
        List<String> names = new LinkedList<>();
        names.add("michael");
        names.add("peter");
        names.add("mark");
        names.add("john");
        names.add("jane");
        //打印集合: 顺序为添加时的顺序
        System.out.println(names);

        //1. 调用集合工具类里的反转方法,将集合元素颠倒过来
        Collections.reverse(names);
        System.out.println("反转后的结果:"+ names);
        //2. 调用工具类里的洗牌(打乱)方法
        Collections.shuffle(names);
        System.out.println("打乱后的结果:"+names);
        //3. 将第二个和倒数第二个做一下交换

        Collection.swap(name,1,names.size()-2);
        System.out.println("交换后的结果:"+names);
        //4. 调用max方法:  底层使用的自然排序,找到最大的
        String ele = Collection.max(names);
        System.out.println(ele);
        //5. 调用min方法: 底层使用的自然排序,找到最小的
        String ele2 = Collections.min(names);
        System.out.println(ele2);
        names.add("michael");
        names.add("michael");
        names.add("michael");
        System.out.println("集合:"+names);
        System.out.println("集合长度:"+names.size());
        //8.调用工具类方法找出michael出现的次数
        int count = Collections.frequency(names, "michael");
        System.out.println("michael出现的次数:"+count);

        //9. 将集合里的所有michael替换成张三
        Collections.replaceAll(names,"michael","张三");
        System.out.println("替换后的样子:"+names);
    }
}








将集合转成Object[] 数组,想使用自己的方法属性有需要强转。
public class CollectionDemo02 {
    public static void main(String[] args) {
        List<String> names = new Arrays<>();
        names.add("michael");
        names.add("peter");
        names.add("mark");


        Object[] arr1 = names.toArray();
        Object obj = arr1[1];\
        if(obj instanceof String){
            String str = (String) obj;
            char ch = str.charAt(1);
             System.out.println(ch);
}

        String[] arr = new String[0];
        String[] arr2 = names.toArray(arr);
        System.out.println(Arrays.toString(arr2));

        if(arr2[0].endsWith("el")){
            System.out.println("是");
        }else {
            System.out.println("不是");
        }
        arr2[0] = "lucy";




    }
}
数组转成的集合能改长度。 放入一个新集合,对新集合进行操作
public class CollectionsDemo03 {
    public static void main(String[] args) {
        String[] names = new String[5];
        names[0] = "michael";
        names[1] = "tom";
        names[2] = "lucy";
        names[3] = "lily";
        names[4] = "John";
        List<String> list = Arrays.asList(names);
        System.out.println(list);
        List<String> arr2 = new ArrayList<>(list);
        arr2.add("张三");
        arr2.add("李四");
        System.out.println(arr2);

        int index = arr2.indexOf("张三");
        Collections.swap(arr2,5,0);
         System.out.println(arr2);

    }

}

  • 17
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值