• Java集合框架(四)


       Collections

       集合框架的工具类

       着重讲解以下方法: 

       1、sort():

       1º根据元素的自然顺序对指定列表按升序进行排序,列表中的所有元素都必须实现comparable接口。

    public static <T extends Comparable<? super T>> void sort(List<T> list)

       2º根据指定比较器产生的顺序对指定列表进行排序。此列表内的所有元素都必须可使用指定比较器相互比较。

    public static <T> void sort(List<T> list, Comparator<? super T> c)

       2、max():

       1º根据元素的自然顺序,返回给定collection的最大元素。collection中的所有元素都必须实现comparable接口。

    public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
    

       2º根据指定比较器产生的顺序,返回给定collection的最大元素。collection中的所有元素都必须可通过指定比较器相互比较。

    public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
    

       3、binarySearch():

       1º使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过sort(List)方法)。

    public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
    

       2º使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据指定的比较器对列表进行升序排序(通过sort(List, Comparator) 方法)。

    public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
    

       示例代码演示上面方法:

    /*
    集合框架的工具类
    Collections:
    */
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class CollectionsDemo {
    
        public static void main(String[] args) {
            //sortDemo();
            //maxDemo();
            binarySearchDemo();
        }
        
        public static void binarySearchDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            list.add("qq");
            list.add("z");
            Collections.sort(list, new StrLenComparator());//指定比较器按字符串长度排序
            
            sop(list);
            
            //int index = Collections.binarySearch(list, "aaaa");
            //int index = halfSearch(list, "aaaa");
            int index = halfSearch(list, "aaaa", new StrLenComparator());
            
            sop("index = " + index);
        }
        
        /* 
         * binarySearch()原理:
         * public static <T> int binarySearch
         * (List<? extends Comparable<? super T>> list, T key)原理:
         * 
         */
        public static int halfSearch(List<String> list, String key) {
            int max, min, mid;
            max = list.size() - 1;
            min = 0;
            
            while(min <= max) {
                mid = (max + min) >> 1;// /2
                String str = list.get(mid);
                
                int num = str.compareTo(key);//获得中间角标的元素
                if(num > 0) {//中间值比目标值大
                    max = mid - 1;
                } else if(num < 0) {//中间值比目标值小
                    min = mid + 1;
                } else {
                    return mid;
                }
            }
            //如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入列表的那一点
            return -min - 1;
        }
        /*
         * binarySearch()带比较器的原理:
         * public static <T> int binarySearch
         * (List<? extends T> list, T key, Comparator<? super T> c)
         */
        public static int halfSearch(List<String> list, String key, Comparator<String> cmp) {
            int max, min, mid;
            max = list.size() - 1;
            min = 0;
            
            while(min <= max) {
                mid = (max + min) >> 1;// /2
                String str = list.get(mid);
                
                //集合中的元素不具备比较性,或者具备的比较性不是我们所需要的,所以应该指定一个Comparator
                int num = cmp.compare(str, key);//此时不能调用compareTo()方法
                
                if(num > 0) {
                    max = mid - 1;
                } else if(num < 0) {
                    min = mid + 1;
                } else {
                    return mid;
                }
            }
            return -min - 1;
        }
        
        public static void maxDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            list.add("qq");
            list.add("z");
            Collections.sort(list);
            sop(list);
            String max = Collections.max(list, new StrLenComparator());
            sop("max = " + max);
        }
        
        public static void sortDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            list.add("qq");
            list.add("z");
            
            sop(list);
            
            Collections.sort(list, new StrLenComparator());
            
            sop(list);
        }
        
        public static void sop(Object obj) {
            System.out.println(obj);
        }
        
    }
    class StrLenComparator implements Comparator<String> {
    
        @Override
        public int compare(String s1, String s2) {
            int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
            
            if(num == 0) 
                return s1.compareTo(s2);
            return num;
        }
        
    }
    View Code

       4、fill():

       1º使用指定元素替换指定列表中的所有元素。

    public static <T> void fill(List<? super T> list, T obj)

       5、replaceAll():

       1º使用另一个值替换列表中出现的所有某一指定值

    public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
    

       6、reverse():

       1º反转指定列表中元素的顺序。

    public static void reverse(List<?> list)
    

       7、reverseOrder():

     1º返回一个比较器,它强行逆转实现了Comparable接口的对象collection的自然顺序。

    public static <T> Comparator<T> reverseOrder()
    

       2º返回一个比较器,它强行逆转指定比较器的顺序。

    public static <T> Comparator<T> reverseOrder(Comparator<T> cmp)
    

       8、shuffle():

       1º使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。

    public static void shuffle(List<?> list)
    

     2º使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。

    public static void shuffle(List<?> list, Random rnd)
    

     示例演示以上方法:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.List;
    import java.util.TreeSet;
    
    
    class StrComparator implements Comparator<String> {
    
        @Override
        public int compare(String s1, String s2) {
            /*
            int num = s1.compareTo(s2);
            if(num > 0)
                return -1;
            if(num < 0)
                return 1;
            return num;
            */
            
            return s2.compareTo(s1);//反转
        }
        
    }
    
    class StringLenComparator implements Comparator<String> {
    
        @Override
        public int compare(String s1, String s2) {
            int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
            
            if(num == 0) 
                return s1.compareTo(s2);
            return num;
        }
        
    }
    public class CollectionsDemo1 {
    
        public static void main(String[] args) {
            //fillDemo();
            //replaceAllDemo();
            
            /*
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            
            fillDemo(list, 1, 3, "liayun");
            */
            
            //orderDemo();
            shuffleDemo();
        }
        
        public static void shuffleDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            list.add("qq");
            list.add("z");
            
            sop(list);
            
            Collections.shuffle(list);//使用默认随机源对指定列表进行置换
            
            sop(list);
        }
        public static void orderDemo() {
            TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StringLenComparator()));
            
            ts.add("abcde");
            ts.add("aaa");
            ts.add("k");
            ts.add("cc");
            
            Iterator<String> it = ts.iterator();
            while(it.hasNext()) {
                sop(it.next());
            }
        }
        
        
        public static void replaceAllDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            
            sop(list);
            
            Collections.replaceAll(list, "aaa", "pp");
            
            sop(list);
            
            Collections.reverse(list);
            
            sop(list);
        }
        /*
        fill()方法可以将list集合中所有的元素替换成指定元素。
        */
        public static void fillDemo() {
            List<String> list = new ArrayList<String>();
            
            list.add("abcd");
            list.add("aaa");
            list.add("zz");
            list.add("kkkkk");
            
            sop(list);
            
            Collections.fill(list, "pp");
            
            sop(list);
        }
        
        //练习:使用fill(),将list集合中部分元素替换成指定元素。
        public static void fillDemo(List<String> list, int start, int end, String str) {
            for(int i = start; i < end; i++) {
                list.set(i, str);
            }
            sop(list);
        }
        
        public static void sop(Object obj) {
            System.out.println(obj);
        }
    
    }
    View Code

       Arrays

       Arrays:用于操作数组的工具类。里面都是静态方法。

       asList:将数组变成list集合。

       问:把数组变成list集合有什么好处?

       答:可以使用集合的思想和方法来操作数组中的元素。

       注意:将数组变成集合,不可以使用集合的增删方法(可以使用contains()/get()/indexOf()/subList()等)。 因为数组的长度是固定的。如果你增删,那么会生成UnsupportedOperationException。

    1. 如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
    2. 如果数组中的元素都是基本数据类型,那么会将该数组(例:[[I@139a55])作为集合中的元素存在。   

       示例代码如下:

    /*
    Arrays:用于操作数组的工具类。
    里面都是静态方法。
    
    asList:将数组变成list集合
    */
    import java.util.Arrays;
    import java.util.List;
    
    public class ArraysDemo {
    
        public static void main(String[] args) {
            //int[] arr = {2, 4, 5};
            //System.out.println(Arrays.toString(arr));
            
            String[] arr = {"abc", "cc", "kkk"};
            
            //把数组变成list集合有什么好处?
            /*
            可以使用集合的思想和方法来操作数组中的元素
            注意:将数组变成集合,不可以使用集合的增删方法。
            因为数组的长度是固定的。
            contains()
            get()
            indexOf()
            subList()
            
            如果你增删,那么会生成UnsupportedOperationException。
            */
            List<String> list = Arrays.asList(arr);
            //System.out.println("contains:" + list.contains("cc"));
            //list.add("qq");//UnsupportedOperationException
            //System.out.println(list);
            
            int[] nums = {2, 4, 5};
            //Integer[] nums = {2, 4, 5};
            
            List<int[]> li = Arrays.asList(nums);
            
            /*
            如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
            如果数组中的元素都是基本数据类型,那么会将该数组([[I@139a55])作为集合中的元素存在。
             */
            System.out.println(li);
        }
    }

       集合变数组:Collections接口中的toArray()方法。

    1. 指定类型的数组到底要定义多长呢?当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。当指定类型的数组长度大于了集合的size,那么就不会新创建数组,而是使用传递进来的数组。所以创建一个刚刚好的数组最优。
    2. 为什么要将集合变数组?为了限定对元素的操作。不需要进行增删了。   

       示例代码如下:

    /*
    集合变数组。
    Collections接口中的toArray()方法
    */
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class ArraysDemo1 {
    
        public static void main(String[] args) {
            ArrayList<String> al = new ArrayList<String>();
            
            al.add("abc1");
            al.add("abc2");
            al.add("abc3");
            
            /*
            1、指定类型的数组到底要定义多长呢?
            当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。
            当指定类型的数组长度大于了集合的size,那么就不会新创建数组,而是使用传递进来的数组
            所以创建一个刚刚好的数组最优
            
            2、为什么要将集合变数组?
            为了限定对元素的操作。不需要进行增删了。
             */
            String[] arr = al.toArray(new String[al.size()]);
            
            System.out.println(Arrays.toString(arr));
        }
    }

       高级for循环

       格式:

    for(数据类型(一般是泛型类型) 变量名 : 被遍历的集合(Collection)或者数组) {
    
    }

       对集合进行遍历,只能获取集合中的元素,但是不能对集合进行操作。迭代器除了遍历,还可以进行remove()集合中元素的动作。如果使用ListIterator,还可以在遍历过程中进行对集合进行增删改查的操作。

       问:传统for和高级for有什么区别呢?

       答:高级for有一个局限性,必须有被遍历的目标。

       建议:在遍历数组的时候还是希望使用传统for,因为传统for可以定义角标。

       示例代码:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    public class ForEachDemo {
    
        public static void main(String[] args) {
            ArrayList<String> al = new ArrayList<String>();
            
            al.add("abc1");
            al.add("abc2");
            al.add("abc3");
            
            for(String s : al) {
                s = "kk";
                //System.out.println(s);
            }
            
            System.out.println(al);
            
            /*
            Iterator<String> it = al.iterator();
            while(it.hasNext()) {
                System.out.println(it.next());
            }
            */
            
            int[] arr = {3, 5, 6};
            for(int i : arr) {
                System.out.println("i:" + i);
            }
            
            HashMap<Integer, String> hm = new HashMap<Integer, String>();
            hm.put(1, "a");
            hm.put(2, "b");
            hm.put(3, "c");
            
            Set<Integer> keySet = hm.keySet();
            for(Integer i : keySet) {
                System.out.println(i + "::" + hm.get(i));
            }
            
            //Set<Map.Entry<Integer, String>> entrySet = hm.entrySet();
            //for(Map.Entry<Integer, String> me : entrySet)
            
            for(Map.Entry<Integer, String> me : hm.entrySet()) {
                System.out.println(me.getKey() + "---------" + me.getValue());
            }
            
         }
    
    }
    View Code

       

       可变参数

       JDK1.5版本出现的新特性。

       可变参数:其实就是上一种数组参数的简写形式,不用每一次都手动的建立数组对象,只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。

       方法的可变参数在使用时注意:可变参数一定要定义在参数列表的最后面。

       示例代码:

    public class ParamMethodDemo {
    
        public static void main(String[] args) {
            //show(3, 4);
            /*
            虽然少定义了多个方法,但是每一次都要定义一个数组,作为实际参数。
            int[] arr = {3, 4};
            show(arr);
            
            int[] arr1 = {3, 4, 7, 5};
            show(arr1);
            */
            
            /*
                      可变参数
                      其实就是上一种数组参数的简写形式,不用每一次都手动的建立数组对象,只要将要操作的元素作为参数传递即可。
                      隐式将这些参数封装成了数组。
            */
            show("haha", 2, 3, 4, 5, 6);
            //show(2, 3, 4, 5, 6, 4, 2, 35, 9, "heiehi");
            //show();
        }
        
        public static void show(String str, int... arr) {
            System.out.println(arr.length);
        }
        /*
        public static void show(int[] arr) {
            
        } 
        */
        
        /*
        public static void show(int a, int b) {
            System.out.println(a + "," + b);
        }
        public static void show(int a, int b, int c) {
            
        }
        */
    }
    View Code

       静态导入

       StaticImport:静态导入

       注意:

    1. 当类名重名时,需要指定具体的包名。
    2. 当方法重名时,指定具备所属的对象或类。

       示例代码如下:

    import static java.util.Arrays.*;//导入的是Arrays类中的所有静态成员。
    
    import java.util.Arrays;
    
    import static java.lang.System.*; //导入了System类中所有静态成员。
    
    
    public class StaticImport {
    
        public static void main(String[] args) {
            out.println("haha");
            int[] arr = {3, 1, 5};
            
            sort(arr);
            
            int index = binarySearch(arr, 1);
            out.println("index = " + index);
            System.out.println(Arrays.toString(arr));//Arrays类中有toString(),Object类中也有toString(),不明确要使用哪个方法。
        }
    
    }
    View Code
  • 相关阅读:
    垂直搜索引擎蜘蛛
    利用Lucene.net搜索引擎进行多条件搜索的做法
    收缩数据库日志文件
    页头加上<!DOCTYPE html PUBLIC "//W3C//>后 js不符合w3c标准 对联不滚动
    winfrom中使用cache
    Vista与XP局域网文件共享设置方法
    如何快速高效的群发Email
    StringTemplate学习笔记(转载)
    清除sql 日志文件
    利用 Sandcastle 编写软件 SDK 文档
  • 原文地址:https://www.cnblogs.com/yerenyuan/p/5263319.html
Copyright © 2020-2023  润新知