• JAVA笔记19-容器之三 Set接口、List接口、Collections类、Comparable接口(重要)


    一、Set接口

    //HashSet综合举例
    import java.util.*;
    public class Test{
        public static void main(String[] args){
            Set<Name> s = new HashSet<Name>();
            s.add(new Name("Li","Ming"));
            s.add(new Name("Sun","Lei"));
            s.add(new Name("Li","Li"));
            System.out.println(s.remove(new Name("Li","Ming")));//equals()方法比较相等不能移除,需要重写hashCode()
            System.out.println(s);//无序的!
            /*
            Iterator t = s.iterator();
            while(t.hasNext()){
                System.out.println(t.next());
                t.remove();
            }
            System.out.println(s);
            */
            //交集、并集
            Set<Name> s2 = new HashSet<Name>();
            s2.add(new Name("Li","M"));
            s2.add(new Name("Sun","Lei"));
            s2.add(new Name("Li","Li"));
            Set<Name> sj = new HashSet<Name>(s);
            sj.retainAll(s2);//交集
            System.out.println(sj);
            Set<Name> sb = new HashSet<Name>(s);
            sb.addAll(s2);
            System.out.println(sb);//并集
        }
    }
    class Name{
        String fn;
        String ln;
        public Name(String fn, String ln){
            this.fn = fn ;
            this.ln = ln ;
        }
        public boolean equals(Object o){
            if(o instanceof Name){
                Name n = (Name)o ;
                return this.fn.equals(n.fn)&&this.ln.equals(n.ln) ;
            }
            return false ;
        }
        public String toString(){
            return fn+" "+ln ;
        }
        public int hashCode(){
            return fn.hashCode();        
        }
    }
      Set集合中的对象不按特定的方式排序,不能包含重复对象。Set容器可以与数学中“集合”的概念相对应。
    注意:如果改变一个Set中的可变元素,导致重复,将会出现问题。
      Set集合由Set接口和Set接口的实现类组成。Set接口实现了Collection接口,因此包含Collection接口的所有方法。J2SDK API中所提供的Set容器类有HashSet类,TreeSet类等。
    1、HashSet类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证Set的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。
    2、TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,因此它在遍历集合时按照自然顺序递增排序,也可以按照指定比较器递增排序,即可以通过比较器对TreeSet类实现的Set集合中的对象进行排序。TreeSet类新增方法如下:
    举例1:
    import java.util.*;  //导入java.util包
    public class Test{
        public static void main(String args[]){
            Set s = new HashSet(); //注意HashSet是无序的,不允许重复的!
            s.add("hello");
            s.add(new Integer(100));
            s.add(new Name("f1","l1"));
            s.add("hello");
            s.add(new Name("f1","l1"));
            System.out.println(s);
        }
    }
    //Name
    class Name{
        private String firstName;
        private String lastName;
        public Name(String firstName,String lastName){
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public String getFirstName(){
            return firstName;
        } 
        public String toString(){  
            return firstName + " " + lastName ;
        }
        public boolean equals(Object obj) {
            if(obj instanceof Name){
                Name name = (Name) obj;
                return (firstName.equals(name.firstName))&&(lastName.equals(name.lastName));
            }
                return super.equals(obj);
        }
        public int hashCode(){
            return firstName.hashCode();
        }
    }
    输出:
    [hello,100,f1 l1]
    注意:Name类应该重写equals()方法。
    举例2:
    import java.util.*;  //导入java.util包
    public class Test{
        public static void main(String args[]){
            Set s1 = new HashSet(); //注意HashSet是无序的!
            Set s2 = new HashSet();
            s1.add("a");
            s1.add("b");
            s1.add("c");
            s2.add("d");
            s2.add("a");
            s2.add("b");
            //Set和List容器类都有Constructor(Collection c)构造方法用以初始化容器类
            Set sn = new HashSet(s1);
            sn.retainAll(s2);//求交集,存入sn
            Set su = new HashSet(s1);
            su.addAll(s2);//求并集,存入su。注意会自动去重!
            System.out.println(sn);
            System.out.println(su);
        }
    }
    输出:
    [b,a]
    [d,b,c,a]

    二、List接口

    List:
      List集合中的元素允许重复,各个元素的顺序就是对象插入的顺序。类似数组,用户可以使用索引(元素在集合中的位置,从0开始)来访问集合中的元素。
      List集合由List接口和List接口的实现类组成。List接口实现了Collection接口,因此包含Collection接口的所有方法。此外List接口还提供下面方法:
      注意:其中add,remove在Collection接口中有,但是形参不同。Collection接口中的声明如下:
      J2SDK所提供的List容器类有ArrayList,LinkedList等。(相当于数组和链表,但是容器类可以自动调节大小)
    1、ArrayList类实现了可变数组,允许元素是NULL。  优点:可根据索引位置对集合进行快速访问。缺点:向指定的索引位置插入对象或删除对象的速度较慢。
    2、LinkedList类采用链表结构保存对象。                优点:便于向集合中插入和删除对象。缺点:对于随机访问集合中的元素效率较慢。
      使用List集合时通常声明为List类型,可通过不同的实现类(ArrayList,LinkedList)实例化集合。例如:
    List list = new ArrayList();
    List list = new LinkedList();
    举例1:List中各种新增方法的使用
    import java.util.*;
    public class Test{
        public static void main(String[] args){
            List<String> l = new LinkedList<String>();
            for(int i=0;i<5;i++){
                l.add("a"+i);
            }
            System.out.println(l);
            l.add(3,"a111");
            System.out.println(l);
            l.set(5,"a11111");
            System.out.println(l);
            System.out.println(l.get(3));
            System.out.println(l.indexOf("a3"));
            System.out.println(l.remove(3));
            System.out.println(l);
            System.out.println(l.remove("a3"));
            System.out.println(l);
        }
    }
    
    
    输出:
    
    

    [a0, a1, a2, a3, a4]
    [a0, a1, a2, a111, a3, a4]
    [a0, a1, a2, a111, a3, a11111]
    a111
    4
    a111
    [a0, a1, a2, a3, a11111]
    true
    [a0, a1, a2, a11111]

     
    举例2:
    import java.util.*;  //导入java.util包
    public class Gather{
        public static void main(String args[]){
            List list = new ArrayList();
            System.out.println(list.size());//0
            list.add("a");
            list.add("b");
            list.add("c");
            System.out.println(list.size());//3
            int i = (int)(Math.random()*(list.size()-1));//随机打印
            System.out.println("随机获取数组中元素:"+list.get(i));
            list.remove(2);
            System.out.println(list);//[a,b]
            for(int j=0;j<list.size();j++){
                System.out.println(list.get(j));//a b
            }
        }
    }

    三、Collections类

      类java.util.Collections提供了一些静态方法实现了基于List容器的一些常用算法。
    举例:
    import java.util.*;  //导入java.util包
    public class Test{
        public static void main(String args[]){
            List l1 = new LinkedList();
            for(int i=0;i<=9;i++){
                l1.add("a"+i);
            }
            System.out.println(l1);
            Collections.shuffle(l1);//随机排序
            System.out.println(l1);
            Collections.reverse(l1);//逆序
            System.out.println(l1);
            Collections.sort(l1);//排序
            System.out.println(l1);
            System.out.println(Collections.binarySearch(l1,"a5"));//折半查找
        }
    }

    输出:

    四、Comparable接口

    问题:上面的算法根据什么确定容器中对象的“大小”顺序?
      所有可以“排序”的类都实现了java.lang.Comparable接口,Comparable接口中只有一个方法:public int compareTo(Object obj);该方法:this==obj时返回0,this>obj时返回正数,this<obj时返回负数。
    实现了Comparable接口的类通过实现compareTo方法从而确定该类对象的排序方式。
    举例:改写Name类,让其实现Comparable接口,其compareTo方法定义为:(String类已经重写了compareTo方法)
    import java.util.*;  //导入java.util包
    public class Test{
        public static void main(String args[]){
            List l1 = new LinkedList();
            l1.add(new Name("Karl","M"));
            l1.add(new Name("Steven","Lee"));
            l1.add(new Name("John","o"));
            l1.add(new Name("Tom","M"));
            System.out.println(l1);
            Collections.sort(l1);
            System.out.println(l1);
        }
    }
    //Name
    class Name implements Comparable{
        private String firstName;
        private String lastName;
        public Name(String firstName,String lastName){
            this.firstName = firstName;
            this.lastName = lastName;
        }
        public String getFirstName(){
            return firstName;
        } 
        public String toString(){  
            return firstName + " " + lastName ;
        }
        public boolean equals(Object obj) {
            if(obj instanceof Name){
                Name name = (Name) obj;
                return (firstName.equals(name.firstName))&&(lastName.equals(name.lastName));
            }
                return super.equals(obj);
        }
        public int hashCode(){
            return firstName.hashCode();
        }
    
        public int compareTo(Object o){
            Name n = (Name) o;
            int lastCmp = lastName.compareTo(n.lastName);
            return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName));
        }
    }
    输出:

    [Karl M, Steven Lee, John o, Tom M]
    [Steven Lee, Karl M, Tom M, John o]

     
  • 相关阅读:
    8 shell五大运算
    android闹钟——原代码【转】
    draw9patch超详细教程【转】
    史上最全的动画效果 Android Animation 总汇 【转】
    Android 中的BroadCastReceiver【转】
    android屏幕适配【转】
    [Android实例] ViewPager多页面滑动切换以及动画效果【转】
    人脸数据库汇总 【转】
    Android闹钟程序周期循环提醒源码(AlarmManager)【转】
    android背景图片更换——经典例子【转】
  • 原文地址:https://www.cnblogs.com/seven7seven/p/3671193.html
Copyright © 2020-2023  润新知