Java集合

作者: 情安 | 来源:发表于2021-06-28 17:26 被阅读0次

    1.Collection接口

    1.1介绍

    英文名称Collection,是用来存放对象的数据结构。其中长度可变,而且集合中可以存放不同类型的对象。并提供了一组操作成批对象的方法。
    数组的缺点:长度是固定不可变的,访问方式单一,插入、删除等操作繁琐。

    1.2 集合的继承结构

    1.3 常用方法测试

    package cn.tedu.collection;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Iterator;
    //这个类用来测试Collection接口
    public class Test1_Collection {
        public static void main(String[] args) {
           //1,创建Collection接口对象
    //     Collection c = new Collection();//报错,因为Collection是接口不能new
           //a,<Integer>是泛型,用来约束集合中元素的类型,只能写引用类型不能是基本类型
           Collection<Integer> c = new ArrayList();
           //2,常用方法
           c.add(100);//添加元素
           c.add(200);
           c.add(300);
           System.out.println(c);
    //     c.clear();//清空集合
           System.out.println( c.contains(300) );//判断集合是否包含指定元素
           System.out.println( c.equals(100) );//判断和100是否相等
           System.out.println( c.hashCode() );//返回集合的哈希码值
           System.out.println( c.isEmpty() );//判断集合是否为空
           System.out.println( c.remove(200) );//判断是否成功删除集合中的元素
           System.out.println( c.size() );//获取集合的长度/个数
           Object[] os = c.toArray();//把集合的元素放入数组
           System.out.println( Arrays.toString(os) );
           //集合间的操作
           Collection<Integer> c2 = new ArrayList();
           c2.add(9);
           c2.add(8);
           c2.add(7);
           c.addAll(c2);//把c2加到c里
           System.outprintln( c.containsAll(c2) );//判断c中是否包含c2
           System.out.println( c.removeAll(c2) );//删除c2
    //     System.out.println( c.retainAll(c2) );//删除c
           System.out.println(c);
           //用来 遍历/迭代 集合中的元素Iterator<E> iterator() 
           Iterator<Integer> it = c.iterator();
           //通过Iterator迭代器,循环着获取集合中的元素
           while(it.hasNext()) {
               //hasNext()用来判断集合中是否有下个元素,有就返回true
               Integer inte = it.next();//next()获取迭代到的元素
               System.out.println(inte);
           }
        }
    }
    

    2.List接口

    2.1介绍

    有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

    2.2常用方法测试

    package cn.tedu.collection;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.ListIterator;
    //这个类用测试List接口
    public class Test2_List {
        public static void main(String[] args) {
           //1,创建List接口对象
           List<String> list = new ArrayList();
           //2,继承自Collection接口的方法
           list.add("jack");//添加元素
           list.add("tony");
           list.add("hanmeimei");
           list.add("tony");
           list.add("tony");
           list.add("tony");
           list.clear();//清空集合
           System.out.println(  list.contains("jack") );
           System.out.println(  list.equals("jack") );
           System.out.println(  list.hashCode() );
           System.out.println(  list.isEmpty() );
           System.out.println(  list.remove("hanmeimei") );
           System.out.println(  list.size() );
           System.out.println(  list.toArray() );//变成数组
           //3,List接口的特有方法    --  都是可以按照索引来操作的方式
           list.add(1, "蔡徐坤");//在指定索引处添加指定的元素
           System.out.println(list+"===");
           System.out.println(list.get(2));//获取下标对应的元素
           System.out.println(list.indexOf("tony"));//获取指定元素第一次出现的下标
           System.out.println(list.lastIndexOf("tony"));//获取指定元素最后一次出现的下标
           System.out.println(list.remove(3));//按照下标删除指定元素
           System.out.println(list.set(0,"xiongda"));//置换元素
           List<String> subList = list.subList(2, 4);//截取下标2-4的元素(含头不含尾)
           System.out.println(subList);
           //TODO 集合间的操作
           List<String> list2 = new ArrayList();
           list2.add("1");
           list2.add("2");
           list2.add("3");
           System.out.println(  list.addAll(list2));//把list2加到list里
           System.out.println(  list.addAll(1, list2));//在指定下标处添加元素
           System.out.println(  list.contains(list2));//判断是否包含
           System.out.println(  list.removeAll(list2));//删除list2
           System.out.println(  list.retainAll(list2));//删除list
           //TODO 集合的迭代  -- List集合的迭代方式有多种:
           //iterator()  listIterator()  for()  foreach
           //方式1:由于List集合有下标,所以可以根据下标遍历数据
                  //i < list.size()  下标最大值是集合长度-1
           for(int i = 0 ; i < list.size() ; i++) {
               String s = list.get(i);//list.get(i)根据下标获取元素
               System.out.println(s);
           }
           //方式2:普通for循环遍历的效率低,可以用foreach提高,好处:语法简洁效率高 坏处:不能按照下标获取
           //for(1 2:3){}  -- 3是要遍历的数据   1是遍历得到的数据的类型   2是变量名
           for(String str:list) {
               System.out.println(str);//str代表的是当前遍历到的数据
           }
           //方式3:iterator() 是继承自父接口Collection的
           Iterator<String> it = list.iterator();
           while(it.hasNext()) {//hasNext()判读是否有下一个元素
               String str = it.next();//next()获取元素
               System.out.println(str);//打印获取到的值
           }
           //方式4:listIterator() 是List接口的特有方法
           //Iterator<E> iterator()  --父接口 --hasNext()  --next() --remove()
           //ListIterator<E> listIterator() --子接口,拥有父接口的方法,也有自己的特有方法(逆向迭代)
           //public interface ListIterator<E>  extends Iterator<E>
           ListIterator<String> it2 = list.listIterator();
           while(it2.hasNext()) {//hasNext()判断后面有没有数据
               String s = it2.next();//next()获取后一个数据
               System.out.println(s);//打印获取到的数据
           }
           //总结:方式3和方式4有什么区别?-- 3是父接口Iterator4是子接口ListIterator
           //子接口拥有父接口的所有方法也有自己的特有方法,子接口的特有方法就是向前/逆向遍历
        }
    }
    

    3.ArrayList实现类

    3.1介绍

    1.存在于java.util包中。
    2.内部用数组存放数据,封装了数组的操作,每个对象都有下标。
    3.内部数组默认初始容量是10,如果不够会以1.5倍容量增长。
    4.查询快,增删数据效率会降低。
    ArrayList的用法和List一样只是创建对象时用的是:

    ArrayList<Integer> list = new ArrayList<>();
    

    4.LinkedList实现类

    4.1介绍

    双向链表,两端效率高,下标遍历效率低,迭代器遍历效率高。底层就是数组和链表实现的。


    4.2常用方法测试

    package cn.tedu.collection;
    import java.util.LinkedList;
    //这个类用来测试LinkedList
    public class Test4_LinkedList {
        public static void main(String[] args) {
           //1,创建对象
           LinkedList<String>  list = new LinkedList();
           //2,常用方法
           list.add("杰克");
           list.add("肉丝");
           list.add("凹凸曼");
           list.add("蜘蛛侠");
           System.out.println(list);
           //3,LinkedList特有方法
           list.addFirst("美队");//添加首元素
           list.addLast("钢铁侠");//添加尾元素
           System.out.println(list);
           System.out.println( list.getFirst());//获取首元素
           System.out.println( list.getLast());//获取尾元素
           System.out.println(  list.removeFirst());//删除首元素
           System.out.println(  list.removeLast());//删除尾元素
        }
    }
    

    5.Set接口

    5.1介绍

    一个不包含重复元素的 collection。数据无序(因为set集合没有下标)。由于集合中的元素不可以重复。常用于给数据去重。HashSet:底层是哈希表。TreeSet:底层是TreeMap,也是红黑树的形式,便于查找数据。

    5.2常用方法测试

    package cn.tedu.collection;
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    //这个类用来测试Set接口的用法
    public class Test5_Set {
        public static void main(String[] args) {
           //1,创建Set对象 
    //     Set set = new Set();//报错,因为Set是接口,不能new
           Set<String> set = new HashSet();
           //2,常用方法 
           set.add("jack");
           set.add("rose");
           set.add("tony");
           set.add("hanmeimei");
           set.add("tony");
           set.add("null");
           System.out.println(set);
           set.clear();//清空集合
           System.out.println(set.contains("tony"));//判断set中是否包含元素
           System.out.println(set.equals("tony"));//判断set是否和tony相等
           System.out.println(set.hashCode());//获取set集合的哈希码值
           System.out.println(set.isEmpty());//判断set集合是否为空
           System.out.println(set.remove("null"));//删除集合的指定元素
           System.out.println(set.size());//获取集合的长度
           Object[] obs = set.toArray();//把集合的元素放入数组中
           System.out.println(Arrays.toString(obs));//查看数组里的元素值
           //集合间的操作
           Set<String> set2 = new HashSet();
           set2.add("1");
           set2.add("2");
           set2.add("3");
           System.out.println(set.addAll(set2));//把set2加入到set中
           System.out.println(set.containsAll(set2));//判断set中是否包含set2
           System.out.println(set.removeAll(set2));//删除set2
           System.out.println(set.retainAll(set2));//删除set
           //集合的迭代Iterator<E> iterator()
           Iterator<String> it = set.iterator();
           while(it.hasNext()) {//判断有没有下一个元素
               String s = it.next();//获取元素
               System.out.println(s);//打印获取到的元素
           }
        }
    }
    

    6.HashSet实现类

    6.1介绍

    底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中。其中,K不许重复。此类允许使用 null 元素。
    HashSet的方法用法和Set一样只是创建对象时用的是:

    HashSet<Integer> set = new HashSet();
    

    7.Set给自定义对象去重

    Set集合去重原理:Set集合去重主要是调用 add 方法时,使用了 hashCode 方法和equals 方法,如果在 Set集合 中找不到与该元素 hashCode 值相同的元素,则说明该元素是新元素,会被添加到 Set 集合中;如果两个元素的 hashCode 值相同,并且使用 equals 方法比较后,返回值为 true,那么就说明两个元素相同,新元素不会被添加到 Set 集合中;如果 hashCode 值相同,但是 equals 方法比较后,返回值为 false ,则两个元素不相同,新元素会被添加到 Set 集合中。
    创建学生类

    package cn.tedu.collection;
    //这个类用来测试set给自定义对象去重
    public class Student {
        //提供构造方法
        public Student() {}
        public Student(String name, int age, String addr) {
           super();
           this.name = name;
           this.age = age;
           this.addr = addr;
        }
    
        //提供私有属性
        private String name;
        private int age;
        private String addr;
    
        //提供set()/get()方法
        public String getName() {
           return name;
        }
        public void setName(String name) {
           this.name = name;
        }
        public int getAge() {
           return age;
        }
        public void setAge(int age) {
           this.age = age;
        }
        public String getAddr() {
           return addr;
        }
        public void setAddr(String addr) {
           this.addr = addr;
        }
    
        //重写toString()
        @Override
        public String toString() {
           return "Student [name=" + name + ", age=" + age + ", addr=" + addr + "]";
        }
    
        //重写hashCode():想要根据两个对象的属性值计算哈希值,
        //如果属性值完全都一样,就保证产生的hash值也一样
        @Override
        public int hashCode() {
           final int prime = 31;
           int result = 1;
           result = prime * result + ((addr == null) ? 0 : addr.hashCode());
           result = prime * result + age;
           result = prime * result + ((name == null) ? 0 : name.hashCode());
           return result;
        }
    
        //重写equals():要比较对象间的属性值,如果属性值都一样,返回true
        @Override
        public boolean equals(Object obj) {
           if (this == obj)
               return true;
           if (obj == null)
               return false;
           if (getClass() != obj.getClass())
               return false;
           Student other = (Student) obj;
           if (addr == null) {
               if (other.addr != null)
                  return false;
           } else if (!addr.equals(other.addr))
               return false;
           if (age != other.age)
               return false;
           if (name == null) {
               if (other.name != null)
                  return false;
           } else if (!name.equals(other.name))
               return false;
           return true;
        }
    }
    

    测试

    package cn.tedu.collection;
    import java.util.HashSet;
    import java.util.Set;
    //这个类用来给自定义对象去重
    //总结:
    //1、如果你想用Set集合,给自定义对象去重,要求你在自己的类中,同时提供重写的hashCode()和equals()
    //--源码摘抄:if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))
    //重写的hashCode():我们不适用默认的自动计算出来的哈希值,而是要根据对象的属性值计算,如果对象的属性值都相同,那么请产生相同的哈希值
    //重写的equals():我们要比较的不是对象的地址值,而是比较,两个对象间如果属性值都一样就返回true
    public class Test7_HashSet2 {
        public static void main(String[] args) {
           //1,创建Set集合对象
           Set<Student> set = new HashSet<Student>();
           //2,向set集合中添加自定义对象
           Student s1 = new Student("tony",20,"BJ");
           Student s2 = new Student("jack",10,"SH");
           Student s3 = new Student("rose",30,"SH");
           Student s4 = new Student("jack",10,"SH");
           Student s5 = new Student("rose",30,"SH");
           set.add(s1);
           set.add(s2);
           set.add(s3);
           //重复的添加了属性相同的对象,为什么没有去重??
           //1,保证对象拥有相同的哈希值??默认使用的是Object提供的hashCode()计算的哈希值
           //如果你想要根据两个对象的属性值计算哈希值,那就需要重写hashCode()
           //2,是要保证两个对象间的equals()返回true,那就需要重写equals()
           set.add(s4);
           set.add(s5);
           System.out.println(set);
        }
    }
    

    相关文章

      网友评论

        本文标题:Java集合

        本文链接:https://www.haomeiwen.com/subject/fcvqultx.html