Java集合框架体系详细梳理,含面试知识点。(三)96 java部落

五、集合框架工具类Collections和Arrays

Collections是集合框架的工具类,里面的方法都是静态的。

** 例1:根据字符串长度的正序和倒序排序。**

用到比较器的地方都可以用Collections.reverseOrder()。

  • static void reverse(List<?> list) 反转指定列表中元素的顺序。
  • static reverseOrder()
  • static reverseOrder(Comparator<T> cmp)
  • <T> Comparator<T> 返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
  • <T> Comparator<T> 返回一个比较器,它强行逆转指定比较器的顺序。

比较器ComparatorByLength.java:

import java.util.Comparator;
 
public class ComparatorByLength implements Comparator<String> {
 
    @Override
    public int compare(String o1, String o2) {
 
        int temp = o1.length() - o2.length();
         
        return temp==0?o1.compareTo(o2): temp;
    }
}
复制代码

Demo:

public static void demo_3() {
 
        // reverse实现原理
        /*
         * TreeSet<String> ts = new TreeSet<String>(new Comparator<String>() {
 
            @Override
            public int compare(String o1, String o2) {
 
                int temp = o2.compareTo(o1);
                return temp;
            }
        });
        */
 
        TreeSet<String> treeset = new TreeSet<String>(new ComparatorByLength());
        treeset.add("abc");
        treeset.add("hahaha");
        treeset.add("zzz");
        treeset.add("aa");
        treeset.add("cba");
        System.out.println(treeset);
 
        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new ComparatorByLength()));//都是静态方法,直接类名调用
 
        ts.add("abc");
        ts.add("hahaha");
        ts.add("zzz");
        ts.add("aa");
        ts.add("cba");
 
        System.out.println("after reverse:\t" + ts);
 
    }
public static void main(String[] args) {
        demo_3();
  }<em id="__mceDel" style="background-color: #ffffff; font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px"><br data-filtered="filtered"></em>
复制代码

运行结果

[aa, abc, cba, zzz, hahaha]
after reverse:    [hahaha, zzz, cba, abc, aa]
复制代码

例2:用工具类Collections.sort()进行排序:

public static void demo_2() {
        List<String> list = new ArrayList<String>();
 
        list.add("abcde");
        list.add("cba");
        list.add("aa");
        list.add("zzz");
        list.add("cba");
        list.add("nbaa");
        System.out.println(list);
 
        Collections.sort(list);
        System.out.println("after sort:\n" + list);
 
        Collections.sort(list, Collections.reverseOrder());
        System.out.println("after reverse sort:\n" + list);
 
        int index = Collections.binarySearch(list, "cba");
        System.out.println("index=" + index);
 
        // 获取最大值。
        String max = Collections.max(list, new ComparatorByLength());
        System.out.println("maxLength=" + max);
    }
    public static void main(String[] args) {
 
        demo_2();
    }  
复制代码

运行结果

[abcde, cba, aa, zzz, cba, nbaa]
after sort:
[aa, abcde, cba, cba, nbaa, zzz]
after reverse sort:
[zzz, nbaa, cba, cba, abcde, aa]
index=2
maxLength=abcde
复制代码

例3:给非同步的集合加锁,方法太多就不一一列举了,自己查看API。(掌握,面试会问到)

  • static <T> Collection<T>
    synchronizedCollection(Collection<T> c)
    返回指定 collection 支持的同步(线程安全的)collection。
  • static <T> List<T>
    synchronizedList(List<T> list)
    返回指定列表支持的同步(线程安全的)列表。
  • static <K,V> Map<K,V>
    synchronizedMap(Map<K,V> m)
    返回由指定映射支持的同步(线程安全的)映射。
  • static <T> Set<T>
    synchronizedSet(Set<T> s)
    返回指定 set 支持的同步(线程安全的)set。

简单说一下给集合加锁的思想。

List list = new ArrayList();// 非同步的list。
 
    list=MyCollections.synList(list);// 返回一个同步的list.
 
class MyCollections{
                 /**
         * 返回一个加锁的List
         * */
        public static  List synList(List list){    
            return new MyList(list);
        }
        // 内部类
        private class MyList implements List{
         
        private List list;
         
        private static final Object lock = new Object();
         
        MyList(List list){ 
            this.list = list;  
        }
         
        public boolean add(Object obj){
            synchronized(lock)
            {
                return list.add(obj);
            }
        }
         
        public boolean remove(Object obj){
            synchronized(lock)
            {
                return list.remove(obj);
            }
        }
     
    }
} 
复制代码

例4:将集合转成数组,Arrays.asList()方法 (掌握)

应用场景:数组方法有限,需要使用集合中的方法操作数组元素时。

注意1:
  数组的长度是固定的,所以对于集合的增删方法(add()和remove())是不能使用的。

Demo:

public static void demo_1() {
 
    String[] arr = { "abc", "haha", "xixi" };
 
    List<String> list = Arrays.asList(arr);
    boolean b1 = list.contains("xixi");
    System.out.println("list contains:" + b1);
    // list.add("hiahia");//引发UnsupportedOperationException
 
    System.out.println(list);
}
复制代码

运行结果

list contains:true
[abc, haha, xixi]
复制代码

注意2:
  如果数组中的元素是对象(包装器类型),那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。(比如上面那个Demo)
  如果数组中的元素是基本数据类型,那么会将该

数组
作为集合中的元素进行存储。(比如下面这个Demo)
Demo:

public static void demo_2() {
    /*
     * 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
     *
     * 如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。
     *
     */
    int[] arr = { 31, 11, 51, 61 };
 
    List<int[]> list = Arrays.asList(arr);
 
    System.out.println(list);
    System.out.println("数组的长度为:" + list.size());
}
复制代码

运行结果

[[I@659e0bfd]
数组的长度为:1
复制代码

由结果可以看出,当数组中的元素时int类型时,集合中存的元素是整个数组,集合的长度为1而不是4。

** 例5:将数组转成集合,List.toArray()方法**

  • Object[]
    toArray()
    Returns an array containing all of the elements in this list in proper sequence (from first to last element).
  • <T> T[]
    toArray(T[] a)
    Returns an array containing all of the elements in this list in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array.

应用场景:对集合中的元素操作的方法进行限定,不允许对其进行增删时。

注意:toArray方法需要传入一个指定类型的数组,数组的长度如何定义呢?
  如果定义的数组长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组。
  如果定义的数组长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。
  所以,一般将数组的长度定义为集合的size。
Demo:

public class ToArray {
    public static void main(String[] args) {
 
        List<String> list = new ArrayList<String>();
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
         
        String[] arr = list.toArray(new String[list.size()]);      
        System.out.println(Arrays.toString(arr));              
    }
}
复制代码

例6:foreach语句
应用场景:遍历数组或Collection单列集合。
     对数组的遍历如果仅仅是获取数组中的元素用foreach可以简化代码,如果要对数组的角标进行操作建议使用传统for循环。

格式:

for(类型 变量 :Collection集合
|数组)
{

}

Demo:

public class ForEachDemo {
 
    public static void main(String[] args) {
         
        // 遍历数组
        int[] arr = { 3, 1, 5, 7, 4 };
         
        for (int i : arr) {
            System.out.println(i);
        }
         
        //遍历List
        List<String> list = new ArrayList<String>();
        list.add("abc1");
        list.add("abc2");
        list.add("abc3");
 
        for (String s : list) {
            System.out.println(s);
        }
 
        // 遍历map
        // 可以使用高级for遍历map集合吗?不能直接用,但是将map转成单列的set,就可以用了。
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(3, "zhagsan");
        map.put(1, "wangyi");
        map.put(7, "wagnwu");
        map.put(4, "zhagsansan");
 
        for (Integer key : map.keySet()) {
            String value = map.get(key);
            System.out.println(key + "::" + value);
        }
 
        for (Map.Entry<Integer, String> me : map.entrySet()) {
            Integer key = me.getKey();
            String value = me.getValue();
 
            System.out.println(key + ":" + value);
        }
 
        // 老式的迭代器写法
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
复制代码
欢迎加入学习交流群569772982,大家一起学习交流。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值