1集合类排序
/**
* 集合类排序:引用类型排序。
* 1. sort()方法要求引用类型必须实现Comparable接口,该接口用于规定实现类是可以比较的。其中的抽象方法comparable用于比较大小
* sort()缺点:修改程序太多--->侵入性,不利于代码的扩展。
* 2. compare()方法重写后:定义了比较大小的和规则,即返回值int表示大小关系,大于0当前对象比参数对象大,小于反之,等于0则相等
* 3. 字符类型的怎么排序?他还是被final修饰的不能继承,实现接口,但是他还有compare方法,所以是怎么比较的呢?
* 如何比较:1.自定义个重载方法的比较类由他来实现重回。
* 重载sort方法要求传入一个额外的比较器,该方法不再要求引用类型必须实现comparable接口,且不用其自身的比较排序规则了。而是使用自己重载的比较排序规则
* 2.匿名内部类的形式创建(因为只使用一次就不必要白白创建一个类了)
* @author lei_l
*
*/
2 队列和栈
/**
* 队列:先进先出
* 栈: 先进后出:为了实现后退这一功能
* @author lei_l
*
*/
public class QueueDemo {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<String>();//符合首尾插入删除快,所以用Linklist
//入队 offer
queue.offer("小李");
queue.offer("java");
queue.offer("计划");
queue.offer("成功");
System.out.println(queue);
//出队 pool
System.out.println(queue.poll());//先进先出
System.out.println(queue);
//引用队首元素,但并不出栈 peek
System.out.println(queue.peek());
System.out.println(queue);
//for循环遍历:问题是会出队列导致数组长度变化,需要反向遍历(一次性的)
for (int i = queue.size(); i >0 ; i--) {
System.out.println(queue.poll());
// System.out.println(queue.peek());//peek会导致只出第一位的元素,遍历不出来
}
System.out.println(queue);
//while形式
while(queue.size()>0) {
System.out.println(queue.poll());
}
System.out.println(queue);
//双端队列即为两边都可进出的栈(方法pop出栈,push入栈)
Deque<String> stack = new LinkedList<String>();
//入栈
stack.push("one");
stack.push("two");
stack.push("three");
stack.push("four");
System.out.println(stack);
//出栈:从栈顶出
stack.pop();
System.out.println(stack);
//peek相同
stack.peek();
System.out.println(stack);
//遍历
while (stack.size()>0) {
System.out.println(stack.pop());
}
System.out.println(stack);
}
3 Map
/**
* Map: 看起来向一个多行两列的表格。存放的是key-vaule键值对,其中key不允许重复(靠key的equals判断)
* 1 常用map:HashMap
* 2.存储方式
* 2.1 按对儿存入put(K,V)输出不是按顺序输出的,输出get(K),删除remove(K k)返回Vaule
* 2.2 put,get的返回值问题:有key改变vaule;覆盖旧值。而返回值这是返回key对应vaule的旧值
* 为解决自动拆箱问题带来的null异常:
* 返回的是包装类intege类型-->相当于自动拆箱了(intVaule),但是为了保证包装类的值不为空(null),导致转型错误,话使用以下方法吧
* 3.实际开发应用:存放每一帧东西。
* 4.遍历map的三种方式:
* 4.1 遍历所有的key :存在一个Set<K> keySet() 将所有的key存入一个set集合中,遍历出即可
* 4.2 遍历所有的key-vaule :存在一个Set<Entry> entry() 将所有的key-vaule存入一个set集合中,遍历出即可
* : map中每一对键值对都是由Map的内部类Entry的一个实例表示的:getKey(),getVaule()两种方法获取key vaule
* 4.3 遍历所有的vaule :存在一个Collection vaules() 将所有vaule返回到一个集合中
* 5.Hashmap遍历快于数组的原因 :hash散列算法以入住酒店为例: 1要求入住 给省份证 put()
* 2 前台获取身份证号码k.hashcode()-->在object中定义的
* 3通过身份证号在前台的登记,计算出您要入住的房间hash散列算法
* 4入住(存入hash数组中)
* 5警察查房:k.get() 通过计算算出在哪个房间
* :为了每一个k的类型都能有hashcode()方法,hashcode在Object类中,十分重要
* :k是否相同:.equals()方法,是否为同一个值(无重写).有无重回写对hashcode方法有着直接的影响
* 遵循的准则(自己定义的类,javaApi中的类自己已经重写好了不用管):
* 1:一致性:当两个对象equals为true时,hashCode返回的数字必须相等。反之不必,但是建议(不然会导致链式存储)
* 2:稳定性:多次比较后hashcode也应该返回的数字相同,不因该是一个变化的值,除非equals比较的属性值也发生了变化
* :为了有两个计算出k的hashcode值不一样的能入住(但是不推荐):在内存中采用链式存储,后放在前(会导致遍历变慢)--->所以高效的唯一识别的hash算法是重要的。
* 6.Hashmap(Hash桶)的装载因子及优化:
* 装载因子:容量Capacity。有初始容量InitialCapcity(初始值为16)个数size 加载因子:Load factor(默认值是75%),当size增加到75%时,会自动扩容数组
* 优化:加载因子小,查找速率快,但浪费Hash桶的内存空间。0.75是一个相对平衡的点。避免超出时的reHash(所有地址重新算,耗时相对比较长)
* @author lei_l
*
*/
4 文件操作
/**
* 文件操作: java.io.file,java中的每一个实例可以表示系统中的一个文件,或者一个目录。
* 使用方式: 1 访问修改目录属性(如:大小,名字,时间)
* 2 操作文件或者目录(创建修改删除)
* boolean exsit()判断文件是否真实存在
* 3 访问目录中的所有内容(但是不能访问文件的数据)
*
* @author lei_l
*
*/
/**
*文件操作:listFiles的过滤器
*对文件的内容的修改:1read():读取一个字节,换算成一个10进制的int值。如果返回-1,则表示文件读取到末尾
* 2 write():往文件中写的话是写二进制的最后8位,写的话是重新写,不是续写。
* 3 randomAccessFile表示操作文件中的呢容
* 3.1RandomAccessFile(String Filename,String mode)mode有读r,读写rw模式(没有只写模式)
* 3.2可以写基本数据类型
* @author lei_l
*
*/
public class FileDemo {
public static void main(String[] args) throws IOException {
//1对文件目录的操作
//不要写绝对路径(会与系统底层又交互) File.separator在windows下表示\,在linux下表示/,在不同的操作系统中鸟是的不同(有利于一次变成到处使用)
File file = new File("."+File.separator+"demo.txt");
System.out.println(file.getName());//名字
System.out.println(file.length());//文件大小
System.out.println(file.isDirectory());//是否为目录
System.out.println(file.isFile());//是否为我文件
System.out.println(file.isHidden());//是否为隐藏
long lastDay = file.lastModified();//最后修改日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(lastDay);
System.out.println(date);
System.out.println(file.canRead());//是否可读
System.out.println(file.canWrite());//是否可写
System.out.println(file.canExecute());//是否?
//2 对文件的操作
//2.1创建文件
File file2 = new File("test.txt");
if (!file2.exists()) {
file2.createNewFile();//创建一个文件
System.out.println("创建完成!");
}else {
System.out.println("文件已存在");
}
//2.2删除文件
File file3 = new File("test1.txt");
if (file3.exists()) {
file3.delete();
System.out.println("删除成功!");
}else {
System.out.println("文件不存在");
}
//2.3创建目录
File dir = new File("test2");
if (!dir.exists()) {
dir.mkdir();
System.out.println("创建成功");
}else {
System.out.println("目录已存在");
}
//2.4创建多级目录
File dir2 = new File("a"+File.separator+"b"+File.separator+"c"+File.separator+"d"+File.separator+"e"+File.separator+"f"+File.separator);
if (!dir2.exists()) {
// dir2.mkdir();//他创建的标准是他的父目录都存在.
dir2.mkdirs();
System.out.println("创建成功!");
}else {
System.out.println("目录已存在!");
}
//2.5删除目录
if (dir.exists()) {
dir.delete();//他的目录里面是空才能删除
System.out.println("删除成功!");
}else {
System.out.println("文件不存在");
}
//3.1 获取当前目录的子项目
File dir3 = new File(".");//
if (dir3.isDirectory()) {//判读是否存在
File[] subs = dir3.listFiles();//当前的目录存放到一个数组中
for(File sub : subs) {
if (sub.isFile()) {
System.out.println(sub.getName()+":是文件");
}else {
System.out.println(sub.getName()+":是目录");
}
}
}
//3.2删除多级目录
delete(dir2);
}
//递归删除
public static void delete(File file) {
if (file.isDirectory()) {
File[] subs = file.listFiles();
for(File sub : subs) {
delete(sub);
}
}
file.delete();
}
}