美文网首页
Java篇-集合

Java篇-集合

作者: TianTianBaby223 | 来源:发表于2018-05-10 16:49 被阅读7次

    在存储的时候通常考虑的对象是数组或者集合,但在java中数组存在一些弊端,一旦创建,其长度不可变,在数组中真实存储的对象个数是个未知数.

    一 : Collection接口

    其子接口有ListSet.
    List接口其主要面向存储有序的,可以重复的元素
    List接口的主要实现类是 ArrayListlinkedList
    ArrayList是List接口的主要实现类,LinkedList面向比较频繁的操作如删除操作,因为其实现方式主要是链表.

    Set接口主要面向的是存储无序的,不可重复的元素
    Set接口的主要实现类为HashSet,LinkedHashSet,TreeSet,Hashtable(子类 : Properties)

    Collection接口提供一些通用的方法,下面一一介绍一下

    • Size();

    返回集合中元素的个数

    Collection coll = new ArrayList();
    System.out.println(coll.size());
    
    • add(Oject obj);

    向集合中添加元素

        Collection coll = new ArrayList();
        coll.add(123);//123 自动转换成包装类
        coll.add("AA");
        coll.add(new Date());
        coll.add("BB");
        System.out.println(coll);
    

    打印结果

    [123, AA, Tue Jul 17 16:59:47 CST 2018, BB]
    
    • addAll

    向集合中添加另一个集合

    Collection coll = new ArrayList();
    coll.add("AA");
    Collection coll1 = Arrays.asList(1,2,3);
    coll.addAll(coll1);
    
    • isEmpty()

    判断集合是否为空

    Collection coll = new ArrayList();
    System.out.println(coll.isEmpty());
    
    • clear() 清空集合元素
    Collection coll = new ArrayList();
    coll.add("AA");
    coll.clear();
    
    • contains(Object obj)

    判断集合是否包含指定的obj元素,如果包含返回true,否则返回false.
    如果存入集合中的元素是自定义类的对象,自定义类要重写equals()方法,添加进List集合的元素(或者对象)所在类一定要重写equals()方法

    Collection coll = new ArrayList();
            coll.add(123);//123 自动转换成包装类
            coll.add("AA");
    boolean b1 = coll.contains(123);
    

    判断是否包含自定义对象

    Person p = new Person();
    boolean b2 = coll.contains(p);
    

    自定义类Person类要重写 equals()方法

    class Person{
    //属性部分
        private String name;
        
        private int age;
        
        public Person() {
            super();
        }
        
    //构造方法
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
    //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;
        }
    
    //重写toString
        @Override
        public String toString() {
            return "person [name=" + name + ", age=" + age + "]";
        }
    
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
    
        //重写equals方法
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            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;
        }
    
    
    • containsAll(coll)

    判断是否包含所有元素

    Collection coll1 = new ArrayList();
            coll1.add(123);
            coll1.add("AA");
            boolean b3 = coll.containsAll(coll1);
    
    • retainAll(coll)

    求当前集合与参数集合的共有元素,返回给当前集合

    Collection coll = new ArrayList();
            coll.add(123);//123 自动转换成包装类
            coll.add("AA");
    
    Collection coll1 = new ArrayList();
            coll1.add(234);
            coll1.add("AA");
    coll.retainAll(coll1);
            System.out.println(coll);
    
    • remove(Object obj)

    删除集合中obj元素,若删除成功返回True,否则返回false

    Collection coll = new ArrayList();
            coll.add(123);//123 自动转换成包装类
            coll.add("AA");
    boolean b = coll.remove("123");
            System.out.println(b);
    
    • removeAll(Collection coll)

    从当前集合中删除包含coll中元素

    coll.removeAll(coll1);
            System.out.println(coll);
    
    • equals(Object obj)

    判断集合中的所有元素是否完全相同

    Collection coll = new ArrayList();
            coll.add(123);//123 自动转换成包装类
            coll.add("AA");
    
    Collection coll1 = new ArrayList();
            coll1.add(234);
            coll1.add("AA");
    System.out.println(coll1.equals(coll2));
    
    • hashCode();

    返回集合哈希值

    Collection coll1 = new ArrayList();
            coll1.add(234);
    System.out.println(coll1.hashCode());
    
    • toArray()

    将集合转化成数组

    Collection coll = new ArrayList();
            coll.add(123);//123 自动转换成包装类
            coll.add("AA");
    Object[] obj = coll.toArray();
            for (int i = 0; i < obj.length; i++) {
                System.out.println(obj[i]);
            }
    
    • iterator()

    返回一个Iterator接口实现类的对象.实现集合的遍历

    Iterator iterator = coll.iterator();
    System.out.println(iterator.next());
            while(iterator.hasNext()) {
                System.out.println(iterator.next());
            }
    

    list接口

    ArrayList

    list的主要实现类

    • 在指定的索引位置index添加元素
    List list = new ArrayList();
            list.add(123);
            list.add(456);
            //在指定的索引位置index添加元素
            list.add(0,55);
    
    • 获取指定索引的元素
    List list = new ArrayList();
            list.add(123);
            list.add(456);
    Object obj = list.get(1);
    
    • 删除指定索引位置的元素
    List list = new ArrayList();
            list.add(123);
            list.add(456);
    list.remove(0);
    
    • 设置指定索引位置的元素
    List list = new ArrayList();
            list.add(123);
            list.add(456);
    list.set(0, 111);
    
    • 返回obj在集合中首次出现的位置 没有的话返回-1
    List list = new ArrayList();
            list.add(123);
            list.add(456);
    list.indexOf(123);
    
    • 返回obj在集合中最后一次出现的位置 没有的话返回-1
    List list = new ArrayList();
            list.add(123);
            list.add(456);
    list.lastIndexOf(456);
    
    • 返回从fromIndex 到toIndex结束的一个子list
    List list = new ArrayList();
            list.add(123);
            list.add(456);
            list.add(new String("aa"));
            list.add(new String("bb"));
            list.subList(0, 3);//不含末尾,包含头 左闭右开
    
    LinkedList

    主要使用链表实现,适用于频繁的操作,其操作放与ArrayList相同

    LinkedList list = new LinkedList();
    list.add(123);
            list.add(456);
            list.add("雪芙");
            list.add("百百");
                    list.set(1, 111);
                    list.remove(0);
            list.get(0);
    /增强for循环/
    for(Object o:list) {
                System.out.println(o);
            }
    

    set接口

    Set接口,存储无序的,不可重复的元素,Set中常用的方法都是Collection下定义的.

    Set存储的元素是无序的,不可重复的!
    1.无序性,无序性!= 随机性 ,真正的无序性指的的是元素在底层存储的位置是无序的
    2.不可重复性,当向Set中添加进相同的元素的时候,后面的这个不能添加进去.

    3.要求添加进Set的元素所在的类,一定要重写equals()hasCode()方法,进而保证Set中元素的不可重复性!

    Set中的元素的存储方式: 使用了哈希算法,当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值决定了此对象在Set中的存储位置,若此位置之前没有对象存储,则这个对象直接存到此位置.若此位置已经有对象存储,再通过equals()比较这两个对象是否相同,如果相同,后一个对象就不能再添加进来
    要求:hashCode()方法要与equals方法一致

    子接口

    • HashSet(主要实现类)
    • LinkedHashSet
    • TreeSet

    • HashSet
    public void testHashSet() {
            Set set = new HashSet();
            set.add(123);
            set.add(456);
            set.add("xf");
            set.add("xf");
            set.add(null);
            Personzz p1 = new Personzz("雪芙", 23);
            Personzz p2 = new Personzz("雨辰", 22);
            System.out.println(p1.hashCode());
            System.out.println(p2.hashCode());
            set.add(p1);
            set.add(p2);
            System.out.println(set.size());
            System.out.println(set);
    
        }
    
    class Personzz  {
        String name;
        Integer age;
    
        public Personzz(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int hashCode() {// return age.hashcode()+name.hashcode(); 没有自带的健壮性好
            final int prime = 31;// 质数
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
    
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Personzz other = (Personzz) obj;
            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;
        }
    
    
    }
    

    打印结果

    1232761
    1236019
    6
    [null, com.TianTianBaby.java.Personzz@12dc33, 456, 123, com.TianTianBaby.java.Personzz@12cf79, xf]
    
    • LinkedHashSet

    使用链表维护了一个添加进集合的顺序,导致我们遍历LinkedHashSet集合元素时,是按照添加进去的顺序遍历的.
    LinkedHashSet插入性能略低于HashSet因为链表要先破坏之前的连接,但在迭代访问Set里的全部元素时有很好的性能.

    public void tesLinkedHashSet() {
            Set set = new LinkedHashSet();
            set.add(123);
            set.add(456);
            set.add("xf");
            set.add("xf");
            set.add(null);
            Iterator iterator = set.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    

    打印结果

    123
    456
    xf
    null
    
    • TreeSet

    ①.向TreeSet中添加的元素必须是同一个类型的
    ②.可以按照添加进集合中的元素的指定的顺序遍历,像String,包装类等默认按照从小到大的顺序遍历

    public void testTreeSet1() {
            Set set = new TreeSet();
            
        // 当Person类没有实现Compareable接口时,当向TreeSet中添加Peronzz对象时,报
            // ClassCastException
            set.add(new Personzz("岑", 22));
            set.add(new Personzz("岑1", 23));
            set.add(new Personzz("岑2", 24));
            set.add(new Personzz("岑3", 24));
            for (Object str : set) {
                System.out.println(str);
            }
        }
    

    打印结果

    com.TianTianBaby.java.Personzz@62fc
    com.TianTianBaby.java.Personzz@b3c4a
    com.TianTianBaby.java.Personzz@b3c6a
    com.TianTianBaby.java.Personzz@b3c6b
    

    ③.自然排序,当向TreeSet中添加自定义类的对象时,有两种排序方法
    自然排序 :要求自定义类实现java.lang.Comparable接口并且重写Compareable(Object obj)在此方法中,指明按照自定义类的哪个属性进行排序.

    class Personzz implements Comparable {
        String name;
        Integer age;
    
        public Personzz(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        public Personzz(String name) {
            super();
            this.name = name;
        }
    
        @Override
        public int hashCode() {// return age.hashcode()+name.hashcode(); 没有自带的健壮性好
            final int prime = 31;// 质数
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
    
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Personzz other = (Personzz) obj;
            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;
        }
    
        // 当向TreeSet中添加Person类的对象时,依据此方法,确定按照那个属性排列
        @Override
        public int compareTo(Object o) {
            // TODO Auto-generated method stub
            if (o instanceof Personzz) {
                Personzz p = (Personzz) o;
                // return this.name.compareTo(p.name) ;
                // return this.age.compareTo(p.age);
                // return -this.age.compareTo(p.age);//倒序
                int i = this.age.compareTo(p.age);
                if (i == 0) {
                    return this.name.compareTo(p.name);
                } else {
                    return i;
                }
            }
            return 0;
        }
    
    }
    

    总结 : 向TreeSet中添加元素时,首先按照CompareTo()方法进行比较,一旦返回0,虽然仅是两个对象的属性值相同,但程序会认为这两个对象是相同的,进而后一个对象不能添加进来,所以CompareTo()hasCode()equals()三者保持一致!

    ④.定制排序
    无法操作类,Compare()与hashCode()以及equals()三者保持一致

    public void testTreeSet2() {
            // 1.创建一个实现了Comparater接口的类对象
    
            Comparator com = new Comparator() {
    
                // 向TreeSet中添加Customer类的对象,在此compare()方法中,指明的是按照customer的哪个属性排序的
                @Override
                public int compare(Object o1, Object o2) {
                    if (o1 instanceof Customer && o2 instanceof Customer) {
                        Customer c1 = (Customer) o1;
                        Customer c2 = (Customer) o2;
                        int i = c1.getId().compareTo(c2.getId());
                        if (i == 0) {
                            return c1.getName().compareTo(c2.getName());
                        }
                        //正序
                        return 1;
    
                    }
    
                    return 0;
                }
            };
            // 2.将此对象作为形参传递给TreeSet的构造器中
            TreeSet set = new TreeSet(com);
            // 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象
            set.add(new Customer("AA", 1003));
            set.add(new Customer("BB", 1004));
            set.add(new Customer("CC", 1005));
            set.add(new Customer("DD", 1006));
            set.add(new Customer("EE", 1006));
            for (Object str : set) {
                Customer cus = (Customer)str;
                System.out.println(cus.getName());
            }
    
        }
    

    打印结果

    AA
    BB
    CC
    DD
    EE
    

    Customer 类

    public class Customer {
        private String name;
        private Integer id;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getId() { 
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public Customer(String name, Integer id) {
            super();
            this.name = name;
            this.id = id;
        }
        
    }
    

    匿名方法

    public void testTreeSet3() {
            // 1.创建一个实现了Comparater接口的类对象
    
            // 2.将此对象作为形参传递给TreeSet的构造器中
            TreeSet set = new TreeSet(new Comparator() {
    
                // 向TreeSet中添加Customer类的对象,在此compare()方法中,指明的是按照customer的哪个属性排序的
                @Override
                public int compare(Object o1, Object o2) {
                    if (o1 instanceof Customer && o2 instanceof Customer) {
                        Customer c1 = (Customer) o1;
                        Customer c2 = (Customer) o2;
                        int i = c1.getId().compareTo(c2.getId());
                        if (i == 0) {
                            return c1.getName().compareTo(c2.getName());
                        }
                        return 1;
    
                    }
    
                    return 0;
                }
            });
            // 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象
            set.add(new Customer("AA", 1003));
            set.add(new Customer("BB", 1004));
            set.add(new Customer("CC", 1005));
            set.add(new Customer("DD", 1006));
            set.add(new Customer("EE", 1006));
            for (Object str : set) {
                System.out.println(str);
            }
        }
    
    

    二 : MAP接口

    • HashMap

    key是用set来存放的,不可重复,value是用Collection来存放的,可重复 一个key-value是一个Entry,所有的Entry是用Set存放的,也是不可重复的.

    向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同,若相同则只能添加进后添加的那个元素.

    public void test1() {
            Map map = new HashMap();
            //向Map中添加一个元素
            map.put("雪芙", 35);
            map.put("雨辰", 32);
            map.put("代劲", 38);
            map.put(null, null);
            map.put("雨辰", 35);
            map.put(new Personzz("馨日",23), 30);
            map.put(new Personzz("馨月",23), 34);
            System.out.println(map.size());
            System.out.println(map);
            
            //按照指定的key删除key-value对
            map.remove("代劲");
            
            //putAll 将一个新的Map中所有元素添加进来
            
            //clear清空
            
            //get获取指定Key的Value值若无此Key 返回null
            map.get("雨辰");
            
        }
    

    Map的遍历方法

    public void test2() {
            Map map = new HashMap();
            //向Map中添加一个元素
            map.put("雪芙", 35);
            map.put("雨辰", 32);
            map.put("代劲", 38);
            map.put(null, null);
            
        }
    

    LinkedHashMap 与 HashMap操作一样

    public void test3() {
            Map map = new LinkedHashMap();
            //向Map中添加一个元素
            map.put("雪芙", 35);
            map.put("雨辰", 32);
            map.put("代劲", 38);
            map.put(null, null);
            map.put(new Personzz("馨日",23), 30);
            Set set1 = map.keySet();
            for(Object obj:set1) {
                System.out.println(obj+"--->>>"+map.get(obj));
            }
        }
    
    • 遍历key集
        Set set = map.keySet();
            for(Object obj : set) {
                System.out.println(obj);
            }
    

    打印结果

    null
    代劲
    雨辰
    雪芙
    
    • 遍历value集
    Collection values = map.values();
            Iterator i = values.iterator();
            while (i.hasNext()) {
                System.out.println(i.next());   
            }
    

    打印结果

    null
    38
    32
    35
    
    • 遍历Key-value对
      方式一
            Set set1 = map.keySet();
            for(Object obj:set1) {
                System.out.println(obj+"--->>>"+map.get(obj));
            }
    

    打印

    null--->>>null
    代劲--->>>38
    雨辰--->>>32
    雪芙--->>>35
    

    方式二

        Set set2 = map.entrySet();
            for(Object obj:set2) {
                Map.Entry entry = (Map.Entry)obj;
                System.out.println(entry.getKey()+"----->"+entry.getValue());
                System.out.println(entry);
            }
    

    打印

    null----->null
    null=null
    代劲----->38
    代劲=38
    雨辰----->32
    雨辰=32
    雪芙----->35
    雪芙=35
    
    

    TreeMap 自然排序 与TreeSet方法相同

    public void test4() {
            Map map = new TreeMap();
            //向Map中添加一个元素
            map.put(new Personzz("aa",23), 30);
            map.put(new Personzz("bb",22), 30);
            map.put(new Personzz("cc",21), 30);
            map.put(new Personzz("dd",21), 30);
            
            Set set1 = map.keySet();
            for(Object obj:set1) {
                System.out.println(obj+"--->>>"+map.get(obj));
            }
        }
    

    TreeMap 定制排序

    public void test5() {
            Comparator com = new Comparator() {
    
                @Override
                public int compare(Object o1, Object o2) {
                    if (o1 instanceof Customer && o2 instanceof Customer) {
                        Customer c1 = (Customer) o1;
                        Customer c2 = (Customer) o2;
                        int i = c1.getId().compareTo(c2.getId());
                        if (i == 0) {
                            return c1.getName().compareTo(c2.getName());
                        }
                        return 1;
    
                    }
    
                    return 0;
                }
            };
            
            TreeMap map = new TreeMap(com);
            map.put(new Customer("aa" , 1001), 80);
            map.put(new Customer("bb", 1002), 81);
            map.put(new Customer("cc", 1003), 82);
            map.put(new Customer("dd", 1004), 83);
            Set set1 = map.keySet();
            for(Object obj:set1) {
                System.out.println(obj+"--->>>"+map.get(obj));
            }
        }
    

    使用properties处理属性文件

    public void test6() throws FileNotFoundException, IOException {
            Properties pros = new Properties();
            pros.load(new FileInputStream(new File("jdbc.properties")));
            String str = pros.getProperty("user");
            String password = pros.getProperty("password");
            System.out.println(str);
            System.out.println(password);
        }
    

    Enumeration接口
    Enumeration 接口是Iterator迭代器的古老版本

    public class TestEnumeration {
      public static void main(String[] args) {
         Enumeration enu = new StringTokenizer("ab-c*-df-g","-");
         while(enu.hasMoreElements()) {
             System.out.println(enu.nextElement());
         }
      }
    }
    

    打印

    ab
    c*
    df
    g
    

    四 : Collections

    操作Collection以及Map的工具类
    使用方法

    public void testCollections1() {
            List list = new ArrayList();
            list.add(123);
            list.add(456);
            list.add(789);
            list.add(15);
            System.out.println(list);
            //反转
            Collections.reverse(list);
            System.out.println(list);
            //随机排序
            Collections.shuffle(list);
            //根据元素的自然排序指定List集合元素按升序排序
            Collections.sort(list);
            
            //根据指定的Compartor产生的顺序对List集合元素进行排序
    //      Collections.sort(list, c);
            
            //swap(List,int i,int j)将指定List集合中的i处元素和j处元素进行交换
            Collections.swap(list, 0, 3);
            
            
        }
    
    public void testCollections2() {
            List list = new ArrayList();
            list.add(123);
            list.add(456);
            list.add(789);
            list.add(15);
            Collections.max(list);
            Collections.min(list);
            
            //返回指定集合中指定元素的出现次数
            int count = Collections.frequency(list, 15);
            System.out.println(count);
            
            //实现List的复制
            //void copy(List dest,list src)将src中的内容复制到desc中
            
    //      List list1 = new ArrayList();//错误的实现方式 
            List list1 = Arrays.asList(new Object[list.size()]);
            Collections.copy(list1, list);
            System.out.println(list1);
            
            //boolean replaceAll(List list,object oldVal ,object newVal)
            //使用新值替换List旧值
            
            //线程安全的 该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时
            //的线程安全问题
            List list2 = Collections.synchronizedList(list);
             System.out.println(list2);
        }
    

    相关文章

      网友评论

          本文标题:Java篇-集合

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