Java学习笔记
链接: jdk13_API.
工具类
Collections
Collection与Collections
Collection与Collections的区别:
Collection是Set,List集合的父类接口,提供了集合框架;
Collections是操作集合的工具类,提供了许多操作集合的静态方法。
方法
- sort(List< T > list)
- sort(List< T > list, Comparator<? super T> c)
- max(Collection<? extends T> coll)
- max(Collection<? extends T> coll, Comparator<? super T> comp)
- min(Collection<? extends T> coll)
- min(Collection<? extends T> coll, Comparator<? super T> comp)
- binarySearch(List<? extends Comparable<? super T>> list, T key)
- binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
- fill(List<? super T> list, T obj)
- replaceAll(List< T > list, T oldVal, T newVal)
- reverse(List<?> list)
- reverseOrder()
- reverseOrder(Comparator< T > cmp)
- shuffle(List<?> list)
示例
package collections;
import java.util.*;
/**
* sort(List<T> list)
* sort(List<T> list, Comparator<? super T> c)
* max(Collection<? extends T> coll)
* max(Collection<? extends T> coll, Comparator<? super T> comp)
* min(Collection<? extends T> coll)
* min(Collection<? extends T> coll, Comparator<? super T> comp)
* binarySearch(List<? extends Comparable<? super T>> list, T key)
* binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
* fill(List<? super T> list, T obj)
* replaceAll(List<T> list, T oldVal, T newVal)
* reverse(List<?> list)
* reverseOrder()
* reverseOrder(Comparator<T> cmp)
* shuffle(List<?> list)
*
* @author 14251
*
*/
class Comp implements Comparator<String>{
@Override
//按照字符串长度排序
public int compare(String o1, String o2) {
Integer s1 = o1.length();
Integer s2 = o2.length();
int num = s1.compareTo(s2);
if(num == 0) {
//长度相同时按照自然顺序排序
return o1.compareTo(o2);
}
return num;
}
}
public class CollectionsDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("ac");
list.add("aac");
list.add("cdsx");
list.add("devpp");
list.add("e");
/*
//sort
print(list);//ac, aac, cdsx, devpp, e
Collections.sort(list);//排序
print(list);//aac, ac, cdsx, devpp, e
Collections.sort(list, new Comp());
print(list);//e, ac, aac, cdsx, devpp
*/
/*
//max
String str1 = Collections.max(list);
System.out.println(str1);//e
String str2 = Collections.max(list, new Comp());
System.out.println(str2);//devpp
*/
/*
//binarySearch
//先要保证List有序(这里的有序不是list的存入有序), 才能使用二分查找
//若元素存在, 返回元素位置, 若元素不存在, 返回: -应插入位置-1
//1. 元素实现Comparable接口, 之后自己使用二分查找
//2. 使用比较器, 之后用带参数的Collections.sort()排序, 再用带参数的二分查找
//自然有序
Collections.sort(list);
System.out.println(list);//[aac, ac, cdsx, devpp, e]
int pos1 = Collections.binarySearch(list, "aac");
System.out.println(pos1);//0
//String按照长度排序
Collections.sort(list, new Comp());
System.out.println(list);
int pos2 = Collections.binarySearch(list, "aac", new Comp());//[e, ac, aac, cdsx, devpp]
System.out.println(pos2);//2
//若元素不存在, 假设按长度排序
int pos3 = Collections.binarySearch(list, "xyz", new Comp());//[e, ac, aac, cdsx, devpp]
System.out.println(pos3);//-4, -(-4)-1=3
*/
/*
//fill
Collections.fill(list, "a");
System.out.println(list);//[a, a, a, a, a]
*/
/*
//replaceAll
System.out.println(list);//[ac, aac, cdsx, devpp, e]
Collections.replaceAll(list, "ac", "abc");//将List中的全部oldVal替换为newVal
System.out.println(list);//[abc, aac, cdsx, devpp, e]
*/
/*
//reverse()
System.out.println(list);//[ac, aac, cdsx, devpp, e]
Collections.reverse(list);
System.out.println(list);//[e, devpp, cdsx, aac, ac]
*/
//reverseOrder
//自然排序
Set<String> set_natural = new TreeSet<String>();
set_natural.addAll(list);
System.out.println(set_natural);//[aac, ac, cdsx, devpp, e]
//反转自然顺序
Set<String> set_natural_reverse = new TreeSet<String>(Collections.reverseOrder());
set_natural_reverse.addAll(list);
System.out.println(set_natural_reverse);//[e, devpp, cdsx, ac, aac]
//长度排序
Set<String> set_length = new TreeSet<String>(new Comp());
set_length.addAll(list);
System.out.println(set_length);//[e, ac, aac, cdsx, devpp]
//反转长度顺序
Set<String> set_length_reverse = new TreeSet<String>(Collections.reverseOrder(new Comp()));
set_length_reverse.addAll(list);
System.out.println(set_length_reverse);//[devpp, cdsx, aac, ac, e]
}
//迭代输出
public static <T> void print(List<T> list) {
Iterator<T> it = list.iterator();
String res = "";
while(it.hasNext()) {//若当前指针后有元素(p)
T t = it.next();//指针后移一位(p+1)
if(t instanceof String) {
String str = (String)t;
if(it.hasNext()) {//后移后的指针后还有元素(p+2), 不是最后一个元素
res += str+", ";
}else {
res += str;
}
}
}
System.out.println(res);
}
}
Arrays
方法
- binarySearch(Object[ ] a, Object key):二分查找,必须保证查找的数组有序
- asList(T… a):数组转换为List< T >集合
- Collection接口的toArray():集合转换为数组
- Arrays.toString(String str):数组转换为字符串
示例
1. 二分查找
package collections;
import java.util.*;
/*
* binarySearch(Object[] a, Object key)
*/
class TestClass /*implements Comparable<TestClass>*/{
String name;
TestClass(String name){
this.name = name;
}
/*
@Override
public int compareTo(TestClass t) {
return this.name.compareTo(t.name);
}
*/
}
class MyCompare implements Comparator<TestClass>{
@Override
public int compare(TestClass t1, TestClass t2) {
return t1.name.compareTo(t2.name);
}
}
public class ArraysBinarySearch {
public static void main(String[] args) {
// ArrayList<TestClass> list = new ArrayList<TestClass>();
// list.add(new TestClass("bac"));
// list.add(new TestClass("cba"));
// list.add(new TestClass("abc"));
// Collections.sort(list, new MyCompare());
Set<TestClass> set = new TreeSet<TestClass>(new MyCompare());
set.add(new TestClass("bac"));
set.add(new TestClass("cba"));
set.add(new TestClass("abc"));
// Collections.binarySearch(list, new TestClass("cba"), new MyCompare());
TestClass[] str = set.toArray(new TestClass[set.size()]);
Arrays.sort(str, new MyCompare());
int res = Arrays.binarySearch(str, new TestClass("cba"), new MyCompare());
System.out.println(res);
char[] ch = {'a', 'b', 'c'};
for(char c : ch) {
System.out.println(c);
}
}
}
2. 其他方法
- 静态导入:
如果一个类包含的方法全是静态成员(属性和方法),那么为了调用简便,可以通过静态导入完成。
格式:import static - 静态导入之后,可以直接书写方法名调用导入的类中的特有的静态方法。如果某些方法与调用类中的方法重名,此时不能简写,必须通过类名.方法名调用。
- import导入的是类,import static导入的是类中的所有静态成员。
package collections;
import java.util.*;
//静态导入
import static java.util.Arrays.*;
/**
* 数组转换为集合
* asList(T... a)
* 集合转换为数组
* Collection接口的toArray()
* 数组转换为字符串
* Arrays.toString(String str)
*
* 增强for循环
*
* @author 14251
*
*/
public class ArrayDemo {
public static void main(String[] args) {
Integer[] arr = {1, 2, 3};
List<Integer> list1 = Arrays.asList(arr);
System.out.println(list1);//[1, 2, 3]
int[] array = {1, 2, 3};
// List<int[]> list2 = Arrays.asList(array);
List<int[]> list2 = asList(array);//静态导入
System.out.println(list2);//[[I@52cc8049]
List<String> list3 = new ArrayList<String>();
list3.add("a");
list3.add("b");
list3.add("c");
//方法1
Object[] obj = list3.toArray();
System.out.println(Arrays.toString(obj));//[a, b, c]
// for(Object o : obj) {
// String str = (String)o;
// System.out.print(str + " ");//a b c
// }
// System.out.println();
//方法2
//Collection中的<T> T[] toArray(T[] a)方法
// String[] str = list3.toArray(new String[0]);
// System.out.println(Arrays.toString(str));//[a, b, c]
// String[] str = list3.toArray(new String[4]);
// System.out.println(Arrays.toString(str));//[a, b, c, null]
String[] str = list3.toArray(new String[list3.size()]);
System.out.println(Arrays.toString(str));//[a, b, c], 不能使用简写为ToString
//因为Object类中也有该方法, 不是Arrays中特有的
HashMap<Integer, String> hm = new HashMap<Integer, String>();
hm.put(1, "a");
hm.put(2, "b");
hm.put(3, "c");
for(Map.Entry<Integer, String> me : hm.entrySet()) {
System.out.println(me.getKey()+ " " + me.getValue());
/*
* 1 a
* 2 b
* 3 c
*/
}
for(Integer i : hm.keySet()) {
System.out.println(i + " " + hm.get(i));
}
}
}
分析
1. 把数组转换成List集合有什么好处?
- 可以使用集合的思想操作数组中的元素。
2. 把集合转换成数组有什么好处?
- 为了限制对元素的操作,不能对数组进行增加、删除操作。
3. Collection接口中的public < T > T[ ] toArray(T[ ] a)方法:
- 使用集合框架中的该方法可以直接指定要转换的数组的类型,避免了无参数的toArray()方法强制转换的麻烦,但是指定的数组的长度应该为多少呢?
假设集合中有3个元素,那么new数组的长度为[0,3]时,虚拟机会自动将所有元素保存在导出的数组中;若长度大于3,那么虚拟机会将多出的部分用null补充。因此,设置的导出数组的长度为集合的长度时最佳,即集合.size()
4. 注意事项:
- 当数组转换成List集合之后,不可以使用集合中的增加、删除方法来操作该集合, 因为数组长度是固定的,因此转换成的List集合的长度也是固定的,可以使用判断方法,例如contains()、get()等。
- 如果数组中的元素是引用数据类型,那么转换成集合时,是将数组中的每个引用对象当作集合中的元素,所以集合的泛型为引用数据类型T(如List< String >);如果数组中的元素是基本数据类型,那么转换成集合时,是将该数组看作一个整体存入到集合中,所以集合的泛型为数组[ ](如List<int[ ]>)。
5. 高级for循环
-
格式:
for(数据类型 变量名 : 被遍历的集合(Collection集合)或数组){ 对数据的操作; }
-
增强for循环只能对集合或数组进行遍历,简化了迭代器iterator()的书写,不能对集合元素本身进行操作。
-
迭代器iterator()除了遍历集合,还可以对集合中的元素进行remove()操作。
-
列表迭代器listIterator()在遍历List集合的同时,可以对集合中的元素进行增删改查。
-
高级for循环使用的前提是必须有被遍历的目标。
-
建议在对数组进行遍历时,使用传统for循环,因为可以利用脚标对数组中的元素进行操作。
Properties类
概述
- Properties是HashTable的子类,因此具有map的特点,是结合了IO和集合的类。
- Properties类的对象可以存储键值对形式的数据,常用来配置文件,在存入数据时,格式必须为键值对形式(键=值)。
- Properties中的数据都是String类型。
存取
方法 | 意义 |
---|---|
getProperty(String key) | 获取key的value |
setProperty(String key, String value) | 设置(key,value) |
package property;
import java.util.Properties;
import java.util.*;
/**
* Properties类的存取
* String getProperty(String key)
* Object setProperty(String key, String value)
* @author 14251
* Properties是HashTable的子类, 因此具有map的特点, 是结合了IO和集合的类
* Properties类的对象可以存储键值对形式的数据, 常用来配置文件, 在存入数据时, 格式必须为键值对形式(键=值)
*/
public class PropertiesDemp {
public static void main(String[] args) {
Properties prop = new Properties();
prop.setProperty("color", "red");
prop.setProperty("background", "white");
System.out.println(prop);//{color=red, background=white}
String str = prop.getProperty("color");
System.out.println(str);//red
Set<String> set = prop.stringPropertyNames();
for(String s : set) {
System.out.println(s+" : "+prop.getProperty(s));
/*
color : red
background : white
*/
}
}
}
加载配置文件
方法 | 意义 |
---|---|
load(InputStream inStream) | 加载配置文件 |
load(Reader reader) | 加载配置文件 |
package property;
import java.util.*;
import java.io.*;
/**
* 演示Properties的load方法, 以及该方法的实现原理
* @author 14251
*
*/
public class LoadDemo {
//load()方法实现原理
public static void loadMethod(String iniDoc) throws IOException{//可以直接传入File对象, 也可以传入String再封装成File对象
/*
* 思想:
* 1. 通过输入流将文件读取到内存
* 2. 读取时, 通过"="将键值对切割
* 3. 调用setProperty()方法, 将数据存入
*/
BufferedReader br = new BufferedReader(new FileReader(iniDoc));
// BufferedWriter bw = new BufferedWriter(new FileWriter(iniDoc));
Properties prop = new Properties();
String line = null;
while((line=br.readLine())!=null) {
String[] str = line.split("=");
prop.setProperty(str[0], str[1]);
}
br.close();
System.out.println(prop);
}
//主函数
public static void main(String[] args) {
try {
loadMethod("E:\\IO\\info.ini");//{color=(244, 221, 208), background=white, pen=red}
} catch (IOException e) {
e.printStackTrace();
}
/* load()
* void load(InputStream inStream)
* void load(Reader reader)
*/
Properties prop = new Properties();
try {
FileReader fr = new FileReader("E:\\IO\\info.ini");
prop.load(fr);
/* 打印: 可以不通过循环
* void list(PrintStream out)
* void list(PrintWriter out)
*/
prop.list(System.out);
/*
-- listing properties --
color=(244, 221, 208)
background=white
pen=red
*/
} catch(Exception e) {
e.printStackTrace();
}
}
}
更新本地配置文件
方法 | 意义 |
---|---|
store(OutputStream out, String comments) | 保存Properties对象信息 |
store(Writer writer, String comments) | 保存Properties对象信息 |
也可以保存为XML文件,具体查看API文档。
package property;
import java.util.*;
import java.io.*;
/**
* 假设软件只能免费试用5次, 每登陆一次计数器减一, 计数器为0时强制用户退出
* @author 14251
*
*/
public class RunCount {
public static void main(String[] args) {
try {
//使用Properties完成
Properties prop = new Properties();
//判断配置文件是否存在
File file = new File("E:"+File.separator+"IO"+File.separator+"info.ini");
if(!file.exists()) {
file.createNewFile();
}
//加载配置文件
FileReader fr = new FileReader(file);
prop.load(fr);
//判断count的次数
int count = 5;
String value = prop.getProperty("UserTime");
if(value!=null) {
count = Integer.parseInt(value);
if(count<=0) {
System.out.println("使用次数已到, 请充值!");
}
}
count--;//更新count
//将新的count值写入配置文件
// if(count<0) {
// count=0;//保证count不会出现负数
// }
prop.setProperty("UserTime", count+"");
/* 存储:
* void store(OutputStream out, String comments)
* void store(Writer writer, String comments)
*/
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
prop.store(bw, "User");
bw.close();
fr.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
Date类
package otherClass;
import java.text.SimpleDateFormat;
import java.util.*;
public class DateDemo {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);//Thu Jun 18 16:49:07 CST 2020
//Date对象的打印结果不便于查看
//使用SimpleDataFormat类对打印结果格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E hh:mm:ss");//传入格式
String str = sdf.format(date);//调用format()方法, 传入Date对象
System.out.println(str);//2020年06月18日 周四 04:49:07
}
}
Calendar类
package otherClass;
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
//Calendar类不能创建对象, 只能通过方法获取对象
Calendar cal = Calendar.getInstance();
//public int get(int field), field是Calendar类中提供的常量值
String year = cal.get(Calendar.YEAR) + "年";
String month = cal.get(Calendar.MONTH) + "月";
String day = cal.get(Calendar.DAY_OF_MONTH) + "日";
String week = "星期" + cal.get(Calendar.DAY_OF_WEEK);
System.out.println(year + month + day + week);//2020年5月18日星期5(2020-6-18-4)
//月份从0开始计算, 星期从周日开始, 因此重新定义月份和星期
System.out.println(getTime(cal));//2020年6月18星期四
//重点add(int field, int amount) - (属性, 偏移量)
cal.add(Calendar.YEAR, 2);
System.out.println(cal.get(Calendar.YEAR));//2022
cal.add(Calendar.DAY_OF_MONTH, -20);
System.out.println(getTime(cal));//2022年5月29日
}
//获取时间
public static String getTime(Calendar c) {
//通过查表法获取对应的月份
String[] Month = {
"1月", "2月", "3月", "4月",
"5月", "6月", "7月", "8月",
"9月", "10月", "11月", "12月"
};
String[] Week = {
"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"
};
int year = c.get(Calendar.YEAR);
String month = Month[c.get(Calendar.MONTH)];
int day = c.get(Calendar.DAY_OF_MONTH);
String week = Week[c.get(Calendar.DAY_OF_WEEK)];
return year+"年"+month+day+"日"+" "+week;
}
}
练习
- 获取任意年的二月有多少天。
- 获取昨天的现在时刻。
package otherClass;
import java.util.Calendar;
public class GetDayDemo {
public static void main(String[] args) {
System.out.println(getFebDay(2020));
System.out.println(getTime());
}
//获取任意年的二月有多少天
public static int getFebDay(int year) {
Calendar c = Calendar.getInstance();
c.set(year, 2, 1);//日期设置为某一年的3月1日
c.add(Calendar.DAY_OF_MONTH, -1);//3月1日后退一天即为二月最后一天
return c.get(Calendar.DAY_OF_MONTH);
}
//获取昨天的现在时刻
public static String getTime() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -1);//今天后退一天即为昨天的现在时刻
return c.get(Calendar.MONTH)+"月"+c.get(Calendar.DAY_OF_MONTH)+"日"
+c.get(Calendar.HOUR_OF_DAY)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND);
}
}
Math类
package otherClass;
import java.util.Random;
/*
* Math类中的一些方法
*/
public class MathDemo {
public static void main(String[] args) {
//1. 幂
double p = Math.pow(2, 3);
System.out.println(p);//8.0
//2. 四舍五入
double r = Math.round(3.14);
System.out.println(r);//3.0
//3. 向上取整, 大于x的最小整数
double c = Math.ceil(6.28);
System.out.println(c);//7.0
//4. 向下取整, 小于x的最大整数
double f = Math.floor(12.56);
System.out.println(f);//12.0
//5. 随机数
for(int i=0; i<10; i++) {
System.out.println(Math.random());//输出[0-1)的随机数
/*
0.2605054528905104
0.49246740134864964
0.23014167966383436
0.347073370214814
0.2976473426537575
0.3119785239575279
0.3296263971497272
0.31950953896042156
0.6131484251716923
0.5133107128932459
*/
System.out.println((int)(Math.random()*10+1));//输出[1-10]的随机数
System.out.println((int)(Math.random()*6+1));//输出[1-6]的随机数(骰子)
}
//Random类中也提供了生成随机数的方法
//nextInt()返回一个int型的随机数, nextInt(int bound)返回一个在[0, bound)内的int型随机数
Random rand = new Random();
for(int i=0; i<10; i++) {
int r1 = rand.nextInt(10)+1;//生成[1-10]的随机数
System.out.println(r1);
}
}
}