Java基础—集合框架(四)

集合框架(四)

一、集合框架工具类

1.Collections工具类
1)定义
Collections工具类用于对集合进行各种操作。

2)常用方法
1> 排序操作

格式:
static void sort(List list):自然排序
static void sort(List list, Comparator c):自定义排序

示例代码:

package com.heisejiuhuche.Collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CollectionsDemo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

        list.add("abcd");
        list.add("aaa");
        list.add("z");
        list.add("kkkkk");
        list.add("qq");
        list.add("zz");

        print(list);

        /* 按自然顺序排序 */
        Collections.sort(list);

        print(list);

        Collections.sort(list, new StrLenComp());

        print(list);
    }

    private static <T> void print(T t) {
        System.out.println(t);
    }
}

/*
 * 自定义排序
 */
class StrLenComp implements Comparator<String> {
    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;
    }
}

程序输出结果:

[abcd, aaa, z, kkkkk, qq, zz]

[aaa, abcd, kkkkk, qq, z, zz]

[z, qq, zz, aaa, abcd, kkkkk]

2> 获取最大元素

格式:
static max(Collection coll): 根据元素的自然顺序,返回指定collection中的最大元素
static T max(Collection coll, Comparator comp):获取指定排序下的最大元素

示例代码(以上述代码为例):

Collections.max(list);
程序输出结果:zz

Collections.max(list, new StrLenComp());
程序输出结果:kkkkk

3> 二分搜索

格式:
static int binarySearch(List<? extends Comparable<? super T>> list, T key):搜索指定元素
static int binarySearch(List<? extends T> list, T key, Comparator<? super T> c):自定义比较器,二分搜索指定元素

示例代码:

Collections.sort(list);
程序输出结果:0

Collections.sort(list, new StrLenComp());
print(Collections.binarySearch(list, "aaa", new StrLenComp()));
程序输出结果:3

4> 替换反转

格式:
static void fill(List<? super T> list, T obj):用指定元素替换集合中所有元素

示例代码:

Collections.fill(list, "java");
print(list);
程序输出结果:[java, java, java, java, java, java]

static boolean replaceAll(List list, T oldVal, T newVal):用新值替换全部旧值
示例代码:

print(list);
Collections.replaceAll(list, "aaa", "java");
print(list);
程序输出结果:
[z, qq, zz, aaa, abcd, kkkkk]

[z, qq, zz, java, abcd, kkkkk]

static void reverse(List<?> list):反转集合元素
示例代码:

print(list);
Collections.reverse(list);
print(list);
程序输出结果:
[z, qq, zz, aaa, abcd, kkkkk]

[kkkkk, abcd, aaa, zz, qq, z]

static void swap(List<?> list, int i, int j):交换List集合指定位置上的元素
示例代码:

Collections.swap(list, 1, 2);
print(list);
程序输出结果:
[abcd, aaa, z, kkkkk, qq, zz]

[abcd, z, aaa, kkkkk, qq, zz]

static void shuffle(List<?> list):随机置换List集合元素
示例代码:

Collections.shuffle(list);
print(list);
程序输出结果:
[abcd, aaa, z, kkkkk, qq, zz]

[z, kkkkk, aaa, qq, abcd, zz]

static Comparator reverseOrder():以自然排序倒序的方式排列元素
示例代码:

TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
ts.add("abcd");
ts.add("aaa");
ts.add("z");
ts.add("kkkkk");
ts.add("zz");
System.out.println(ts);
程序输出结果:
[zz, z, kkkkk, abcd, aaa]自然顺序倒序排序

static Comparator reverseOrder(Comparator cmp):反转现有比较器顺序
示例代码:

TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenComp()));
ts.add("abcd");
ts.add("aaa");
ts.add("z");
ts.add("kkkkk");
ts.add("zz");
System.out.println(ts);
程序输出结果:
[kkkkk, abcd, aaa, zz, z]反转自定义比较器顺序排序

5> 线程同步

static List synchronizedList(List list):返回线程同步安全的List集合

2.Arrays工具类
1)定义
Arrays工具类用于对数组进行各种操作。

2)常用方法
1>输出数组:String toString()

示例代码:

package com.heisejiuhuche.Collection;

import java.util.Arrays;

public class ArraysDemo {
    public static void main(String[] args) {
        int[] arr = new int[]{2, 4, 5, 7};

        System.out.println(Arrays.toString(arr));
    }
}

程序输出结果:[2, 4, 5, 7]

2> 将数组转换为List集合

static List asList(T… a):使用集合的思想和方法操作数组中元素

示例代码:

package com.heisejiuhuche.Collection;

import java.util.Arrays;
import java.util.List;

public class ArraysDemo {
    public static void main(String[] args) {
        /* 引用数据类型 */
        String[] string = {"abc", "kkk", "aq"};

        List<String> strList = Arrays.asList(string);

        System.out.println(strList);

        /* 基本数据类型 */
        int[] arr = new int[]{2, 4, 5, 7};

        List<int[]> arrList = Arrays.asList(arr);

        System.out.println(arrList);

        /* 引用数据类型 */
        Integer[] integer = {2, 4, 5, 7};

        List<Integer> intList = Arrays.asList(integer);

        System.out.println(intList);
    }
}

程序输出结果:

[abc, kkk, aq]
[[I@15db9742]
[2, 4, 5, 7]

注意:
-将数组变成集合,不能使用集合的增删方法;因为数组的长度是固定的;可以使用判断和获取方法;如果做增删操作,会发生UnsupportedOperationException;
-如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素;如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存储

3> Collection接口将集合转换为数组

T[] toArray(T[] a)

示例代码:

package com.heisejiuhuche.Collection;

import java.util.ArrayList;
import java.util.Arrays;

public class CollectionToArrayDemo {
    public static void main(String[] args) {
        ArrayList<String> al= new ArrayList<String>();

        al.add("arbc");
        al.add("abdc");
        al.add("afbc");

        String[] string = al.toArray(new String[al.size()]);

        System.out.println(Arrays.toString(string));
    }
}

程序输出结果:[arbc, abdc, afbc]

注意:
-集合转换成数组是为了限定对元素的操作;不能进行增删,只能进行查找获取;
-当指定类型的数组长度小于集合的size,那么toArray()方法内部就会创建一个新的数组,长度为集合的size;当指定类型的数组长度大于集合的size,就使用传递进来的数组;开发过程中,创建一个长度刚好的数组效率最优,故使用al.toArray(new String[al.size()]);

二、增强for循环

1.功能
增强for循环简化了代码,但是其局限性在于,只能对集合的元素进行取出操作,无法修改。

2.与传统for循环的区别
增强for循环有一个局限性,必须有被遍历的目标。建议在遍历数组的时候使用传统for循环,因为传统for循环可以定义下标,方便元素操作。

3.格式

for(数据类型 变量名 : 被遍历的集合(Collection)或数组)

示例代码:

package com.heisejiuhuche.Collection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class EnhancedForDemo {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 5, 7, 9};

        for(int x : arr) {
            System.out.println(x);
        }

        ArrayList<String> al = new ArrayList<String>();

        al.add("java01");
        al.add("java02");
        al.add("java03");
        al.add("java04");

        for(String str : al) {
            System.out.println(str);
        }

        HashMap<Integer, String> hm = new HashMap<Integer, String>();

        hm.put(01, "java04");
        hm.put(02, "java05");
        hm.put(03, "java06");

        /* keySet取出元素 */
        for(Integer i : hm.keySet()) {
            System.out.println(i + ":::" + hm.get(i));
        }
        /* entrySet取出元素 */
        for(Map.Entry<Integer, String> me : hm.entrySet()) {
            System.out.println(me.getKey() + "----" + me.getValue());
        }
    }
}

程序输出结果:

3
5
7
9
java01
java02
java03
java04
1:::java04
2:::java05
3:::java06
1----java04
2----java05
3----java06

注意:
在使用增强for循环输出List集合的时候,如果集合上没有定义泛型,for循环中也不能指定输出的变量类型,只能写Object

三、JDK5.0之后新特性

1.可变参数
1)功能
可变参数省去了当参数类型相同,而参数个数不同时的方法重载,简化了代码。

2)格式
public void method(参数类型... 参数名)

3)应用
在使用可变参数的时候,虚拟机隐式地将传入的参数封装成数组,传给method()方法。

示例代码:

package com.heisejiuhuche.Collection;

public class ParamDemo {
    public static void main(String[] args) {
        show();
    }

    private static void show(int... arr) {
        System.out.println(arr);
    }
}

程序输出结果:[I@15db9742,这是一个数组对象。

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

示例代码:

package com.heisejiuhuche.Collection;

public class ParamDemo {
    public static void main(String[] args) {
        show(1, "abc", "cdd", "eee");
    }

    private static void show(int a, String... str) {
        System.out.println(a);
        for(int x = 0; x < str.length; x++) {
            System.out.println(str[x]);
        }
    }
}

程序输出结果:

1
abc
cdd
eee

如果写成private static void show(String... str, int a),编译报错。

2.静态导入
1)功能
当被使用的一个类中全部都是静态成员的时候,可以将这个类的静态成员全部导入;那么之后在使用这个类的静态成员时,不需要指定类名(同名方法除外),简化代码;这样的导入方式称为静态导入。

2)格式
import关键字后加上staticimport static java.util.Arrays.*;

3)应用

示例代码:

package com.heisejiuhuche.Collection;

/* 到处Arrays工具类中的所有静态成员 */
import static java.util.Arrays.*;

import java.util.Arrays;

public class StaticImport {
    public static void main(String[] args) {
        int[] arr = {3, 5, 1, 6, 7, 9};

        sort(arr);
        int index = binarySearch(arr, 1);
        /* 和Object类当中的toString()方法重名,那么Arrays类名必须指定 */
        System.out.println(Arrays.toString(arr));
        System.out.println("index: " + index);
    }
}

程序输出结果:

[1, 3, 5, 6, 7, 9]
index: 0

四、API中其他对象

1.System类
1)定义
System类包含一些有用的类字段和方法。它的成员都是静态的。 该类不能被实例化。

2)常用方法
获取系统属性信息:Properties getProperties();
PropertiesHashTable的子类,存储的键值对都是字符串,可以通过Map的方法取出该集合中的元素。

示例代码:

package com.heisejiuhuche.api;

import java.util.Map;
import java.util.Properties;

public class SystemDemo {
    public static void main(String[] args) {
        Properties prop = System.getProperties();

        /* 设置自定义属性 */ /* 输出结果:myProp:myValue */
        System.setProperty("myProp", "myValue");

        /* 获取指定属性信息 */ /* 输出结果:Windows 8.1 */
        String str1 = System.getProperty("os.name");
        System.out.println(str1);

        /* 获取所有属性信息 */
        for(Object obj : prop.keySet()) {
            String str = (String)prop.get(obj);
            System.out.println(obj + ":" + str);
        }
    }
}

部分系统信息:

java.runtime.name:Java(TM) SE Runtime Environment
sun.boot.library.path:C:\Program Files\Java\jre1.8.0_25\bin
java.vm.version:25.25-b02
user.country.format:CN

2.Runtime类
1)定义
每个Java应用程序都有的使应用程序能和其运行环境相连接的类。该类不能被实例化,通过getRuntime()方法获得其实例。Runtime类运用了单例设计模式。

2)常用方法
执行命令:exec(command)
该方法可以打开指定的或Path路径中的应用程序。

示例代码:

package com.heisejiuhuche.api;

import java.io.IOException;

public class RuntimeDemo {
    public static void main(String[] args) {
        Runtime r = Runtime.getRuntime();

        try {
            /* 打开记事本 */
            r.exec("notepad  java.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上述代码可以用记事本打开java.txt文件

3.Date类
1)定义
Date类表示特定的瞬间。该类允许将时间解释为年、月、日、小时、分钟和秒值,也允许格式化和解析日期字符串。

2)常用方法
格式化日期:format(Date d)
利用SimpleDateFormat类中的format()方法,格式化Date对象。

示例代码:

package com.heisejiuhuche.api;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateDemo {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);

        /* 声明SimpleDateFormat对象,初始化时间格式 */
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日E hh:mm:ss");

        /* 调用format()方法格式化当前时间 */
        System.out.println(sdf.format(d));
    }
}

程序输出结果:

Wed Apr 08 21:59:18 CST 2015
2015年04月08日星期三 09:59:18

4.Calendar类
1)定义
Calendar类是一个抽象类,它为日期时间提供了一些方法,来操作日历字段。

2)常用方法
获取指定日期字段:int get(int field)
自定义日期字段:void set()
给指定日期字段添加或减去指定时间量:void add(int field, int amount)

示例代码:

package com.heisejiuhuche.api;

import java.util.Calendar;

public class CalendarDemo {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();

        System.out.println(c.get(Calendar.YEAR) + "年");
        System.out.println((c.get(Calendar.MONTH) + 1) + "月");
        System.out.println(c.get(Calendar.DAY_OF_MONTH) + "日");
        System.out.println("第" + c.get(Calendar.WEEK_OF_MONTH) + "周");
        System.out.println("星期" + (c.get(Calendar.DAY_OF_WEEK) - 1));
        c.set(Calendar.YEAR, 2500);
        System.out.println(c.get(Calendar.YEAR) + "年");
        c.add(Calendar.DAY_OF_MONTH, 5);
        System.out.println(c.get(Calendar.DAY_OF_MONTH) + "日");

    }
}

程序输出结果:

2015年
4月
9日
第2周
星期4
2500年
14日

5.Math类
1)定义
Math类封装了进行如加减乘除底数对数等的基本数学运算的方法。

2)常用方法
获取大于或等于指定数字的最小整数:double ceil(double a)
获取小于或等于指定数字的最大整数:double floor(double f)
四舍五入:long round(double d)
获取指定数字的指定次幂:double pow(double a, double b)
获取带正号的大于等于0.0且小于1.0之间的double值:double random()
使用Random类:Random r = new Random()

示例代码:

package com.heisejiuhuche.api;

import java.util.Random;

public class MathDemo {
    public static void main(String[] args) {
        Random r = new Random();
        System.out.println(Math.ceil(12.34));
        System.out.println(Math.floor(12.34));
        System.out.println(Math.round(12.56));
        System.out.println(Math.pow(2, 4));

        for(int x = 0; x < 3; x++) {
            System.out.println(Math.random());
        }
        /* 获取1到10(包含)的随机数 */
        System.out.println(r.nextInt(10) + 1);
    }
}

程序输出结果:

13.0
12.0
13
16.0
0.7995736092536022
0.4545334778512139
0.09122601733494085
8