1.输出格式double的小数位精确
Scanner sc = new Scanner(System.in);
sc.next() 读取空白字符结束的字符串
sc.nextLine() 读取回车结束的字符串 使用nextInt nextDouble next() 之后再使用nextLine会有问题
不要在nextDouble() nextInt() 、next()等之后使用nextLine()
/t tab
/n 换行
/f 换页
/r 回车
Math.random() 返回0到1之间,不包括1,包括0.0
Math.pow(x,2)
Math.abs() 绝对值
Math.sqrt() 平方根
Math.min() max()
return 0>=hp?true:false;
Character.isDigit(ch) 是否数字
。。。。.isLetter(ch) 是否字母
.toLowerCase(ch)
.toUpperCase(ch)
String.length(0
String.charAt(index)
String.concat(String s1)
String.toUpperCase()
String.toLowerCase(0
String.trim() 去掉空白符包括转义字符
String.equals(s1)
String.equalsIgnoreCase(s1)
String.compareTo(s1) 返回字符串比较后的差值,
String.compareToIgnoreCase(s1)
String.startsWith(特定前缀)返回true
String.endWith(特定后缀)
String.contains(s1) 是否包含子串
String.replace('h','j')
String.substring(beginIndex) 指定索引到结尾
String.substring(beginIndex,endIndex) 指定索引到结束索引,不包含结束索引
这个方法是全小写!!!!
String.indexOf(ch) 返回第一个出现字符 ch 的索引,无匹配,则返回-1
String.indexOf(ch, fromIndex) 从开始索引fromIndex后出现的第一个ch
String.indexOf(String s)
syso 输出 一个整数+Object对象 会报错,需要在中间加一个 “ ”就自动转成字符串
int value = Integer.parseInt(intString) 将数字内容的字符串转换为数字 若超出int 范围会如何?
或char '9' - '0'
字符串转为字符串的list:
Arrays.asList(myStr.split(","))
如何将数字转换为字符?
String.valueOf(9) + String1
数字int 或long 转字符串 + “”
int i = 5; Integer it = i; String str = it.toString();
字符转字符串 char c + 字符串即可自动转型
string 和int之间的转换
string转换成int :Integer.valueOf("12")
int转换成string : String.valueOf(12)
char和int之间的转换
首先将char转换成string
String str=String.valueOf('2')
Integer.valueof(str) 或者Integer.ParseInt(str)
Integer.valueof返回的是Integer对象,Integer.paseInt返回的是int
int转成数字型char字符 加上 48再强制转换,因为 ASCII 编码 48 到 57 为字符 '0' ~ '9' 的编码。
A到Z 65--90 中间6个字符[ \ ] ^ _ ` 小写从 a 97 a~z 97-122
int 和 string 的逆序
类似 double
java中 double 类型只是一个简单类型,是不能其输出位数及精度是固定的
可以利用其它方法进行位数输出,如:
方法一、使用
Math.round()
Double value = 0.254668;
(double)Math.round(value*100)/100
public static void main(String[] args) {
// 1. 使用 String.format() 方法
double data = 11.8982389283293;
System.out.println(String.format("%.2f", data));
// 2. 使用 printf 输出
printf(%n) %n也是换行,和\n的区别在于,%n具有跨平台性
System.out.printf("%.2f", data);
// 3. 使用 DecimalFormat 对象格式化
DecimalFormat format = new DecimalFormat("#.00");
System.out.println(format.format(data));
多重循环跳出和继续用标识符
% 是 10 % 2 == 0
while ( a || b ) do .. 需要a 和b均不成立才能跳出循环
数组:
int [] list = new int [length];
myList.length
处理数组随机打乱:每个下标元素随机产生一个下标互换
foreach
for (double e :myList ){
仅能用于遍历数组
sout(e); 不能用myList[e]
}
二分查找
选择排序
冒泡排序
for (int n = 0 ; n
if (list[i]>list[i+1]){
temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
}
}
}
java.util.Arrays.sort(list[])
java.util.Arrays.parall(list[]) 多处理器并行操作
java.util.Arrays.binarySearch(list[],number) 升序排列后二分查找 若不存在元素则返回 -(插入点下标+1)
java.util.Arrays.fill(list[],number)
java.util.Arrays.fill(list[],beginIndex,endIndex,number)
java.util.Arrays.toString(list[])
System.arraycopy(list,0,newList,0,list.length) 复制整个数组,需先初始化 newList
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];
System.arraycopy(a1, 1, a2, 3, 3);
System.out.println(Arrays.toString(a1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
public static void method(int...arg) args实际上是数组
startTime = System.currentTimeMillis();
endTime = System.currentTimeMillis();
executionTime = endTime - startTime;
Arrays.toString(list) 除char数组打印toString可以显示数组内容,其他的直接syso打印的都是对象地址,所有可以使用Arrays.toString(list)来打印数组的内容
String.length()
数组中除了交换值,还可以交换索引值
扑克牌随机洗牌:随机生成索引值进行互换
System.currentTimeMillis()获取当前毫秒值
Date类:
java.util.Date date = new java.util.Date();
date.getTime()
date.toString() Mon Dec 26 07:43:39 EST 2011
Random():以当前时间为种子创建Random对象
javafx.geometry.Point2D
Point2D p1 = new Point2D(x1,y1);
p1.distance(p2);
String 类
welcome.replace('e','A') wAlcomA
welcome.replaceFirst("e","AB") wABlcome
welcomw.replace("e","AB") wABlcomAB
replaceAll("","")
"Java#HTML#Perl".split("#") Java HTML Perl 字符串数组
“Java”.toCharArray()
String.valueOf( new char[] {'j','a','v','a'} );
正则表达式
Integer.parseInt(str)
String.matches("Java.*")
\d 单个数字位 \d{3} 三个数字
“a+b+#]","NNN") aNNNbNNNNNNc
String.format("%7.2f%6d%-4s",45.556,14,"AB")
-45.56--14AB-
StringBuilder.append(“”)
子父类构造方法链
多态:父类变量可以指向子类对象
变量的声明类型和实际类型
方法调用时 按照引用变量的实际类型(new 的类型)
ArrayList
add(Object o) add(3,Object o)在指定位置添加对象
clear()
size()
contains( Object o)
get(int index)
indexOF(Object o)
isEmpty()
remove(Object o) 移除并返回元素
set(in index,Object o)
new ArrayList
设计一个ArrayList,使得这个ArrayList里,又可以放Hero,又可以放Item,但是除了这两种对象,其他的对象都不能放:
首先创建一个接口 LOL,不需要在其中声明任何方法
接着让Hero和Item都实现LOL接口
最后,声明一个ArrayList的变量lolList,它的泛型是
List
这样在lolList中就即放Hero对象,又放Item对象了。
遍历ArrayList的三种方法:
增强for循环:
迭代器Iterator
Iterator
while (it.hasNext() )
Hero h = it.next();
next方法中首先调用了checkForComodification方法,该方法会判断modCount是否等于expectedModCount,不等于就会抛出java.util.ConcurrentModificationExcepiton异常
modCount是ArrayList的一个属性,继承自抽象类AbstractList,用于表示ArrayList对象被修改次数
在iterator.remove()方法中,同样调用了ArrayList自身的remove方法,但是调用完之后并非就return了,而是expectedModCount = modCount重置了expectedModCount值,使二者的值继续保持相等。
针对forEach循环并没有修复方案,因此在遍历过程中同时需要修改ArrayList对象,则需要采用iterator遍历
上面提出的解决方案调用的是iterator.remove()方法,如果不仅仅是想调用remove方法移除元素,还想增加元素,或者替换元素,是否可以呢?浏览Iterator源码可以发现这是不行的,Iterator只提供了remove方法。
但是ArrayList实现了ListIterator接口,ListIterator类继承了Iter,这些操作都是可以实现的
ListIterator
增强for中调用list.remove()也会报java.util.ConcurrentModificationExcepiton,但是可以调用其他list的remove()方法
LinkedList:
序列分先进先出FIFO,先进后出FILO
FIFO在Java中又叫Queue 队列
FILO在Java中又叫Stack 栈
LinkedList还实现了双向链表结构Deque,可以很方便的在头尾插入删除数据
什么是链表结构: 与数组结构相比较,数组结构,就好像是电影院,每个位置都有标示,每个位置之间的间隔都是一样的。 而链表就相当于佛珠,每个珠子,只连接前一个和后一个,不用关心除此之外的其他佛珠在哪里。
MyLinkdedList.addLast(Object o)
MyLinkdedList.addFirst(Object o)
MyLinkdedList.getFirst(Object o)
MyLinkdedList.getLast(Object o)
MyLinkdedList.removeFirst()
MyLinkdedList.removeLast()
LinkedList同时实现了Queue队列接口:
Queue
MyQueue.offer(Object o)
Hero h = q.poll() //取出队列第一个元素
q.peek() 查看第一个元素
ArrayList 和 LinkedList 区别:
1.ArrayList 插入,删除数据慢,查找索引和定位很快
2.LinkeList 插入,删除数据块,查找索引 和定位慢
在0索引插入数据 LinkedList比ArrayList快
在 最中间索引插入数据, ArrayList比LinkedList快,后者需要每次都查找中间的索引
在最后面添加元素,ArrayList也比LinkedList快 但是差不太多
二叉树:
排序:
假设通过二叉树对如下10个随机数进行排序
67,7,30,73,10,0,78,81,10,74
排序的第一个步骤是把数据插入到该二叉树中
插入基本逻辑是,小、相同的放左边,大的放右边
练习-比较冒泡法,选择法以及二叉树排序的性能区别
创建4万个随机数,然后用分别用冒泡法,选择法,二叉树3种排序算法进行排序,比较哪种更快
HashMap:
键不能重复,值可以重复
以相同的key 把不同的value插入到 Map中会导致旧元素被覆盖,只留下最后插入的元素
HashMap 存储数据的方式是 键值对
HashMap
添加键值对:dictionary.put("adc", "物理英雄");
获取值:dictionary.get("t")
//清空:heroMap.clear();
HashSet:
Set中的元素,
不能重复 没有顺序。
严格的说,是没有按照元素的插入顺序排列
Set不提供get()来获取指定位置的元素
所以遍历需要用到迭代器,或者增强型for循环
通过观察HashSet的源代码(如何查看源代码)
可以发现HashSet自身并没有独立的实现,而是在里面封装了一个Map.
HashSet是作为Map的key而存在的
LinkedHashSet的既不重复,又有顺序
java.util.Collections.sort(ArrayList) 数值和字符串进行排序
java.util.Collections.max(ArrayList)
java.util.Collections.min(ArrayList)
java.util.Collections.shuffle(ArrayList) 随机打乱
异常捕获:
异常是一种对象,从异常类继承 java.lang.Throwable
异常:Exception: ClassNotFoundException IOException RuntimeException(ArithmeticException NullPointEception IndexOutOfBoundsException IllegalArgumentException )
Throwable:
error + Eception:
RuntimeException
error和RuntimeException及其子类为免检异常,即编译器不会进行检查,因为这些错误进行处理没有意义,因为一旦出错就需要停止程序来修改代码,其他的错误可以捕获并进行剩下的操作
RuntimeException及其子类异常无须声明抛出异常
原方法中抛出异常被捕获,则可以继续执行原方法直至结束,异常不会抛给调用这个方法的main方法,未被捕获才会一直往上抛,直到虚拟机
系统错误:Error: LinkageError VirtualMachineError
浮点数除以0 不会报错,会显示Infinity 无穷大 整数除以0抛异常
Long.MAX_VALUE + 1 变成负 即 MIN_VALUE
声明异常 在方法参数后声明要throw的异常
抛出异常:
捕获异常:
try中出现异常,整个try代码块会跳出
如果try 抛出异常,try中其余语句会被跳过
catch 父类的异常则 可以捕获所有子类的异常
父类catch出现在子类catch之前会报错,应先catch子类的异常,再catch 父类异常
方法调用会先被原方法中的catch捕获
无论是否有异常产生,均执行:finally
try {
statements;
}catch (Exception){
handling ex;
}finally{
finalStatements;
}
如果没有异常:执行finalStatements,再执行try语句的下一条
有异常并被捕获:执行catch和finally后再继续之后的语句
如果异常没被捕获:跳过try 执行finally 并将异常传递给方法调用者
即使finally 有return语句,finally 还是会执行
Exception.printStackTrace() 先打印接收到的最近的异常路径,再打印调用者的调用者,一直到最开始出现异常的方法中
链式异常: throw new Exception(“New info from method1 ”, ex)
方法头不应该声明error和runtimeException 只声明IOException类似的受查异常(checked Exception)
日期格式处理:
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal=Calendar.getInstance();
y=cal.get(Calendar.YEAR); MONTH DATE HOUR_OF_DAY MINUTE SECOND
Date dt = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss aa");
temp_str=sdf.format(dt);
创建文件:
public boolean createNewFile()
new File(String parentPath,String fileName或dirName)在指定父目录下新建文件或目录,可扩展性更高,parentPath可以作为参数接收
FileWriter fw = new FileWriter(file,true) true代表追加内容
PrintW
File file = new File("C:\a.txt");
file.createNewFile();
创建目录:
public boolean mkdir()
public boolean mkdirs() 若父文件夹不存在,则创建父文件夹
同样在File 的构造方法参数中传文件夹的路径
删除文件或文件夹
public boolean delete()
String getName() 返回路径中最后部分表示的文件或文件名
long length() 返回路径中表示的文件的字节数
String getAbsolutePath() 获取绝对路径的String对象
File getAbsoluteFile() 获取绝对路径的对象
new File("C:\Users\q06285\Desktop\qzqz")
String getName()
同样在File 的构造方法参数中传文件夹的路径
boolean exists() 判断File构造方法中封装路径是否存在
boolean isDirectory() 判断是不是文件夹
boolean isFile() 判断是不是文件
static File[] listRoots() 列出可用的文件系统根
String[] list() 获取File构造方法中路径的文件和文件夹名。遍历一个目录,返回文件名
File[] listFiles() 返回的是指定目录下的文件和文件夹的全路径
文件过滤器:
自定义过滤器,实现FileFilter接口,重写抽象方法 accept
public String[] list(FilenameFilter filter)
public File[] listFiles(FileFilter filter) 参数为自己重写的过滤器实现FileFilter接口
字节流:InputStream OutputStream
字符流:Reader Writer
IO程序:
使用前:导入IO
使用时:进行IO异常处理
使用后:释放资源(finally)
void write(byte[] b)
void write(byte[] b,int startIndex,int length)
FileOutputStream fos = new FileOutputStream("C:we.txt")
创建流对象后调用write方法写数据
byte[] bytes = {65,66,67,68};
fos.write(bytes);
写入字符串:fos.write("hello".getBytes() );
文件追加 类型shell的>>
new FileOutputStream("C:we.txt",true);
换行:
fos.write("123\r\nworld".getBytes());
IOException :
//try 外面声明变量,try 里面建立对象
FileOutputStream fos = null;
try{
fos = new FileOutputStream("s:\a.txt");
fos.write(100);
}catch(IOException ex){
System.out.println(ex);
throw new RuntimeException("文件写入失败,重试");
}finally{
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("关闭资源失败");
}
}
字节输入流 FileInputStream
(char)new FileInputStream("c.txt").read();返回读取的一个字节,文件尾返回-1
int len = read(byte[] b) 读取一定数量字节,存储到缓冲区的数组b中
len 表示读取到多少个有效字节,若不是正好读取到最后一个字节,则会重新往回读取,但byte数组的长度为有效字节的个数,超过文件尾的数组其余部分为倒序的数组
java.io.Write
write(int c) int值的ASCII码
write(char[] c)
write(char[] c,int index,int length)
write(String s)
int read() 读取单个字符
int read(char [] cbuf) 将字符读到char数组中,返回值为成功读取的字符数
创建URL对象后,用URL.openStream()方法打开输入流
java.io.File file = new java.io.File("Score.txt");
Scanner in = new Scanner(file);
java.io.PrintWriter output = new java.io.PrintWriter(file) 如果文件不存在,则创建该文件
output.close();
new Scanner(Paths.get("
c:\mydirectory\myfile.txt"),"UTF-8");
完成一个批量改名的小程序
聊天程序
上传文件的程序
高速复制文件
身份证自动生成
读取配置文件模拟多账号登录
计算器 记事本 日记软件 网页聊天室 课程管理系统 人事管理系统 支付平台(https://zhuanlan.zhihu.com/p/29502554)
Runtime.addShutdownHook
日志:
Logger.getGlobal().info("File->Open menu item selected");
Logger.getGobal().setLevel(Level,OFF);
try{
Thread.currentThread().sleep(5 * 1000);
} catch (InterruptedException e){ }
多线程:
并发:一个时间段内的同时运行
并行:同一时刻点同时运行
线程调度:
分时调度
抢占式调度:Java 实有抢占式,优先级高的优先运行,相同的优先级随机选择
继承Thread类创建并启动线程:
1.定义Thread类的子类,重写run()方法,方法体代表线程需要完成的任务
2.创建该子类的对象,即创建了线程对象
3.调用线程对象的start()启动线程
实现Runnable 接口创建线程:
1.实现Runnable 接口,重写run()方法
2.new Thread( ).start() 传递Runnable 的实现类的对象,并调用start方法
线程方法:
Thread.sleep(1000); 表示当前线程暂停1000毫秒 ,其他线程不受影响,
抛出InterruptedException 中断异常
myThread.join() 加入到当前线程,相当于插队,主线程会等待该线程结束完毕, 才会往下运行。
设置线程优先级:
t1.setPriority(Thread.MAX_PRIORITY); 最大优先级10 为最能抢占CPU时间
t2.setPriority(Thread.MIN_PRIORITY);
Thread.yield() :
yield和sleep的主要是,yield方法会临时暂停当前正在执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续运行
守护线程的概念是: 当一个进程里,所有的线程都是守护线程的时候,结束当前进程。
myThread.setDaemon(true)
正则表达式:
X 匹配指定字符
. 匹配任意单个字符
(ab|cd) 匹配ab或cd
[abc] 匹配a、b或c
[^abc] 匹配a、b、c以外的字符
[a-z] 匹配a-z的任意字符
[^a-z] 匹配除a-z的任意字符
[a-e[m-p]] 匹配a-e或m-p
[a-e&&[c-p]] 匹配a-e和c-p的交集
\d 匹配个位数字
\D 匹配一位非数字
\w 匹配单词字符
\W 匹配单个非单词字符
\s 匹配空白字符space
\S 匹配非空白字符
p* 匹配p的0次或多次出现
p+ 匹配p的1次或多次出现
p? 匹配p的0次或1次出现
p{n} 匹配p的正好n次出现
p{n,} 匹配p的至少n次出现
p{n,m} 匹配p的出现次数位于n和m之间,不包含
饿汉单例模式:
准备一个类属性,指向一个实例化对象。 因为是类属性,所以只有一个
public static getInstance()方法,提供给调用者获取定义的唯一一个对象
懒汉单例模式:
//准备一个类属性,用于指向一个实例化对象,但是暂时指向null
public static getInstance()方法,返回实例对象
第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
懒汉延迟加载,但线程不安全,饿汉线程安全,但较慢
内部类:分为 非静态内部类 静态内部类 匿名类 本地类
非静态内部类:只有 一个外部类对象存在时才有意义
new 外部类().new 内部类()
作为Hero的非静态内部类,是可以直接访问外部类的private实例属性name的
静态内部类:不需要外部类的实例化作为基础
new. 外部类.静态内部类(); 与非静态内部类的区别在于,非静态内部类的语法是调用了外部类的构造器new对象,再调用了内部类的构造器
因为没有一个外部类的实例,所以在静态内部类里面不可以访问外部类的实例属性和方法(即 非静态成员和非静态方法)
除了可以访问外部类的私有静态成员外,静态内部类和普通类没什么大的区别
泛型:
lambda 表达式:
方法参数:
filter(heros,h->h.hp>100 && h.damage<50);
private static void filter(List
for (Hero hero : heros) {
if(checker.test(hero))
System.out.print(hero);
}
}
核心技术读书笔记:
接口不是类,而是对类的一组需求描述,描述类具有什么功能
lambda 表达式:一种表示可以在将来某个时间点执行的代码块的简洁方法,使用一种精巧简洁的方式表示使用回调或变量行为的代码
代理:一种实现任意接口的对象
接口:
实现接口时 使用泛型,可以在编译期就发现类型转换的错误,
如果不用泛型,还需要进行强制转换才能进行比较
class Employee implements Comparable
public int compareTo(Employee other){
return Double.compare(salary,other.salary)
}
}
class Employee implements Comparable{
public int compareTo(Object otherObject){
Employee other = (Employee) otherObject;
return Double.compare(salary,other.salary)
}
}
每个compareTo 方法 应该在开始进行检测:
if (getClass != other.getClass() ) throw new ClassCastException
整数比较:整数绝对值不超过 (Integer.MAX_VALUE-1)/2 ,可以直接用减法,否则,使用
Integer.compare的静态方法进行比较
浮点数比较:相近的两个浮点数进行减法,可能会得到0,所有需要使用 Double.compare(x,y)方法 x Arrays.sort(Object[] a) a数组元素需 实现 Comparable接口 接口静态方法: 接口默认方法:必须 使用 default修改方法