Java集合

Java集合

import java.time.DayOfWeek;
import java.util.*;
import java.util.function.Consumer;

//Collection是除Map外所有集合类的根接口,是一个interface,继承Iterable接口
//List:一种有序列表的集合,例如,按索引排列的Student的List; //有序列表的集合
//Set:一种保证没有重复元素的集合,例如,所有无重复名称的Student的Set;//没有重复元素的集合,没有顺序
//Map:一种通过键值(key-value)查找的映射表集合,例如,根据Student的name查找对应Student的Map。 //key,value,其中key不重复
public class JavaCollection {
//    1。list,有序列表
//    和数组一样,添加,删除元素,如果是中间的元素,需要移动元素。使用ArrayList,就自动帮我们做了。
//我们考察List<E>接口,可以看到几个主要的接口方法:
//
//    在末尾添加一个元素:boolean add(E e)
//    在指定索引添加一个元素:boolean add(int index, E e)
//    删除指定索引的元素:E remove(int index)
//    删除某个元素:boolean remove(Object e)
//    获取指定索引的元素:E get(int index)
//    获取链表大小(包含元素的个数):int size()
//    一个是ArrayList,还有一个是LinkedList
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        System.out.println(linkedList.get(0));
        System.out.println(linkedList.pop());
//        System.out.println(linkedList.pop());
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(2);

        Object[] array = list.stream().toArray();
        for (Object obj:array){
            System.out.println(obj);
        }

//        单独使用List
        List<String> list1 = List.of("apple","pear","banana");
        list1.contains("apple");
//        list1.add("good"); // not supported, because list.of return a immutable object.
        System.out.println(list1);

        List<Integer> list11 = List.of(12, 34, 56);
//        通过new Interger[5]来生成指定5个数量的数组,然后会把list的数据放进去
//        then array1 is free to modify, no reference indict to any elements in it.
        Integer[] array1 = list11.toArray(new Integer[5]);
        for (Integer n : array1) {
            System.out.println(n);
        }

//        test for equals method.
        List<String> list_string = List.of("A","B","C");
        System.out.println(list_string.contains("A"));
        System.out.println(list_string.indexOf("A"));

        System.out.println(list_string.indexOf("BC"));
        System.out.println(list_string.contains(new String("C"))); // true or false?
        System.out.println(list_string.indexOf(new String("C"))); // 2 or -1?
        //contains 是调用对象的equals方法对比的,
        //如果放入了new Person("Bob"),但是用另一个new Person("Bob")查询不到,原因就是Person类没有覆写equals()方法。
        class Person{
            public String firstname;
            public String lastname;
            public int age;

            Person(String firstname,String lastname,int age){
                this.firstname = firstname;
                this.lastname = lastname;
                this.age = age;
            }

            @Override
            public boolean equals(Object obj) {
                if (obj instanceof Person){
                    Person p = (Person) obj;
                    return Objects.equals(this.firstname,p.firstname) &&Objects.equals(this.lastname,p.lastname) && p.age==this.age;
                }
                return false;
            }

            @Override
            public int hashCode() {
//                int h =0;
//                h = 31*h + this.firstname.hashCode();
//                h = 31*h + this.lastname.hashCode();
//                h = 31*h + age;
//                return h;
//                if firstname == null will result error
//                so we use Objects(utils) .hash
//                the passed variable must be used in equals method.
                return Objects.hash(firstname,lastname,age);
            }
            //            因此,我们总结一下equals()方法的正确编写方法:
//
//            先确定实例“相等”的逻辑,即哪些字段相等,就认为实例相等;
//            用instanceof判断传入的待比较的Object是不是当前类型,如果是,继续比较,否则,返回false;
//                    对引用类型用Objects.equals()比较,对基本类型直接用==比较。
//                    使用Objects.equals()比较两个引用类型是否相等的目的是省去了判断null的麻烦。两个引用类型都是null时它们也是相等的。
//
//            如果不调用List的contains()、indexOf()这些方法,那么放入的元素就不需要实现equals()方法。
        }
        List<Person> persolist =  List.of(new Person("aaa","bbb",111));
        System.out.println(persolist.contains(new Person("aaa","bbb",111)));

        Map<DayOfWeek, String> map = new EnumMap<>(DayOfWeek.class);
        map.put(DayOfWeek.MONDAY, "星期一");
        map.put(DayOfWeek.TUESDAY, "星期二");
        map.put(DayOfWeek.WEDNESDAY, "星期三");
        map.put(DayOfWeek.THURSDAY, "星期四");
        map.put(DayOfWeek.FRIDAY, "星期五");
        map.put(DayOfWeek.SATURDAY, "星期六");
        map.put(DayOfWeek.SUNDAY, "星期日");
        System.out.println(map);
        System.out.println(map.get(DayOfWeek.MONDAY));

        Set<String> set = new HashSet<>();
        set.add("apple");
        set.add("banana");
        set.add("pear");
        set.add("orange");
        for (String s : set) {
            System.out.println(s);
        }

        Set<String> set1 = new TreeSet<>();
        set1.add("apple");
        set1.add("banana");
        set1.add("pear");
        set1.add("orange");
        for (String s : set1) {
            System.out.println(s);
        }
//        Queue 是个接口,表示单端队列,Deque是一个接口,表示双端队列
        Deque deque = new LinkedList();
        //LinkedList即实现了List接口,又实现了Queue接口,
        // 但是,在使用的时候,如果我们把它当作List,就获取List的引用,如果我们把它当作Queue,就获取Queue的引用:
        LinkedList ls = new LinkedList();
        // 始终按照面向抽象编程的原则编写代码,可以大大提高代码的质量。

//        还有一个优先级队列,比如VIP充了钱,他排队就可以到前面了
        //PriorityQueue和Queue的区别在于,它的出队顺序与元素的优先级有关,
        // 对PriorityQueue调用remove()或poll()方法,返回的总是优先级最高的元素。
        // 因此,放入PriorityQueue的元素,必须实现Comparable接口,PriorityQueue会根据元素的排序顺序决定出队的优先级。
        Queue prioriqueue = new PriorityQueue<Person>(new Comparator<>() {
            @Override
            public int compare(Person o1, Person o2) {
                if(o1.age == o2.age){
                    return 0;
                }
                return o1.age>o2.age?-1:1;
            }
        });

        Person p1 = new Person("1","2",15);
        Person p2 = new Person("1","2",16);
        Person p3 = new Person("1","2",17);

        prioriqueue.offer(p1);
        prioriqueue.offer(p3);
        prioriqueue.offer(p2);
        System.out.println("---------------");
        System.out.println(((Person)prioriqueue.poll()).age);
        System.out.println(((Person)prioriqueue.poll()).age);
        System.out.println(((Person)prioriqueue.poll()).age);
        System.out.println("---------------");

//        stack 栈
        Stack stack = new Stack<>();
        stack.add("1");
        stack.add(2);
        stack.add(new Person("jian","ge",1));
        for (Object obj:
             stack) {
            if (obj instanceof Person){
                obj = (Person) obj;
            }
            System.out.println(obj);
        }

//        Iterator
        ReversList list_res = new ReversList();
        list_res.add(1);
        list_res.add(3);
        list_res.add(2);
        for(Iterator<Integer> iterator1 = list_res.iterator();iterator1.hasNext();){
            int s = iterator1.next();
            System.out.println(s);

        }

//        Collections 不是 Collection类,这个Collections提供了很多集合操作的工具方法,都是静态函数。
        //addAll()方法可以给一个Collection类型的集合添加若干元素。
        // 因为方法签名是Collection,所以我们可以传入List,Set等各种集合类型。
//        Collections.addAll()
//        Collections提供了一系列方法来创建空集合:
//
//        创建空List:List<T> emptyList()
//        创建空Map:Map<K, V> emptyMap()
//        创建空Set:Set<T> emptySet()
//        此外,也可以用各个集合接口提供的of(T...)方法创建空集合。例如,以下创建空List的两个方法是等价的:
//
//        List<String> list1 = List.of();
//        List<String> list2 = Collections.emptyList();
//        要注意到返回的空集合是不可变集合,无法向其中添加或删除元素。
        System.out.println("-----------------");
        ArrayList<Integer> my_listr = new ArrayList<>(List.of(5,3,2,7,6));
        my_listr.add(4);
        Collections.sort(my_listr);
        for (int i:
             my_listr) {
            System.out.println(i);
        }
        System.out.println("-----------------");
        Collections.shuffle(my_listr);
        for (int i:
                my_listr) {
            System.out.println(i);
        }
        System.out.println("-----------------");
        List list_unmodify =  Collections.unmodifiableList(my_listr);
//        list_unmodify.add(1); //will result error.
//        if not delete the original reference, the original reference may modify the elements in the list.
        my_listr = null;
//        my_listr.add(1);
        for (Object i:
                list_unmodify) {
            System.out.println(i);
        }


    }


}


//一个自定义集合或者数据类型要能够迭代的话,需要实现Iterable接口,
class ReversList<T> implements Iterable {
    private List<T> list = new ArrayList<>();

    public void add(T t){
        list.add(t);
    }

//    这个返回Iterable的函数是必须要实现的。
    @Override
    public Iterator iterator() {

        return new ReversIterator(list.size());
    }

    class ReversIterator implements Iterator<T>{

        int size;
        int index = -1;

        ReversIterator(int size){
            this.size = size;
        }

        @Override
        public boolean hasNext() {
            return size>0;
        }

        @Override
        public T next() {
            size--;
            index++;
            return ReversList.this.list.get(index);
        }
    }
//      这两个函数在接口中是有默认实现的
//    @Override
//    public void forEach(Consumer action) {
//        Iterable.super.forEach(action);
//    }
//
//    @Override
//    public Spliterator spliterator() {
//        return Iterable.super.spliterator();
//    }
}

//最后,Java访问集合总是通过统一的方式——迭代器(Iterator)来实现,它最明显的好处在于无需知道集合内部元素是按什么方式存储的。

//由于Java的集合设计非常久远,中间经历过大规模改进,我们要注意到有一小部分集合类是遗留类,不应该继续使用:
//        Hashtable:一种线程安全的Map实现;
//        Vector:一种线程安全的List实现;
//        Stack:基于Vector实现的LIFO的栈。
//还有一小部分接口是遗留接口,也不应该继续使用:
//        Enumeration<E>:已被Iterator<E>取代。

//Java的集合类定义在java.util包中,支持泛型,主要提供了3种集合类,包括List,Set和Map。
//        Java集合使用统一的Iterator遍历,尽量不要使用遗留接口。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值