本文会持续更新,如果对您有帮助的话可以点点关注,双击
本人2021年蓝桥杯C++B组国二,今年转战Java,并整理此文,希望能够对大家有所帮助,第一次写这么长的文章,可能有的地方写的不是很好,还请大家多多谅解,我会持续进行改进并且更新。
第七届蓝桥杯国赛题解
第八届蓝桥杯国赛题解
第九届蓝桥杯国赛题解
第十届蓝桥杯国赛题解
第十一届蓝桥杯国赛题解
注:内容为蓝桥杯来自蓝桥杯决赛特训营
Scanner s = new Scanner(System.in); //声明一个从控制台中读入数据的对象
int x = s.nextInt();
double x = s.nextDouble();
String x = s.next(); //无法读入空格
String x = s.nextLine(); //可以读入空格,遇到换行停止
while(s.hasNext()) { //hasNext() 判断还有没有读入值 相当于while(scanf())
//如果有字符,返回true,否则阻塞
//hasNext()不会返回false
}
s.hasNextInt(); //判断输入是否为int,是则返回,否则阻塞
s.hasNextDouble(); //判断输入是否为double,是则返回,否则阻塞
System.out.println();
System.out.print();
System.out.printf(); //格式化输出
prinf()函数与C++中的prinf相同
print()和println()的区别是println()换行
通过重写函数的形式来缩写输入和输出,具体情况如下所示
static int gtInt() {
int x = sc.nextInt();
return x;
}
static void print(int x) {
System.out.print(x);
}
static void println(int x) {
System.out.println(x);
}
构造:
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));
int x = r.read(); //读取一个字符并将其转换为UTF-8的值
eg: 输入123213123,x只能读取到1
String x = r.readLine(); //读取一行的值
String[] x = r.readLine().split(' '); //分割字符形成字符串
需要注意的是 在windows中按一下回车键 一共有两个字符 “\n\r” 而read()只能读取一个字符所以如要要用read来达到吸收回车的目的,需要用两个read(); 如果用readLine()的话会将"\n\r"全部吸收 , 所以只需要一个readLine()来吸收回车
w.write(x);
w.write("\n");
w.flush();
w.write(Integer.toString(x)); //输出int型变量
需要注意的是 write() 不能直接输出int类型, 因为write(int a) 会输出其对应的ASCii码的字符
eg:write(65); => A
由于java是面向对象的语言,所以这里将快读和快写封装成类比较好用一些
StreamTokenizer读取字符类型,而BufferedReader读取字符串这里买呢StreamTokenizer也可以读取字符串,但是不会读取特殊符号和数字,所以我们最好用BufferedReader读取
static class FastRead {
StreamTokenizer streamTokenizer; //读取数字
BufferedReader bufferedReader; //读取字符串
public FastRead() {
streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
br = new BufferedReader(new InputStreamReader(System.in));
}
int gtInt() throws IOException {
streamTokenizer.nextToken();
int x = (int) streamTokenizer.nval;
return x;
}
long gtLong() throws IOException {
streamTokenizer.nextToken();
long l = (long) streamTokenizer.nval;
return l;
}
double gtDouble() throws IOException {
streamTokenizer.nextToken();
double x = streamTokenizer.nval;
return x;
}
String gtString() throws IOException {
String s = bufferedReader.readLine();
return s;
}
}
快速输出这里我们选用的是printWriter
static class FastWrite {
PrintWriter printWriter;
public FastWrite() {
printWriter = new PrintWriter(new OutputStreamWriter(System.out));
}
void print(int x) {
printWriter.print(x);
}
void print(String sc) {
printWriter.print(sc);
}
void print(double x) {
printWriter.print(x);
}
void println(int x) {
printWriter.println(x);
}
void println(double x) {
printWriter.println(x);
}
}
Java的运算速度比C++慢,所以我们可以计算一下运行时间来判断是否会超时
long startTime = System.currentTimeMillis(); //获取开始时间
yourcode(); //你的代码
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
int arr[] = new int[100];
int arr[][] = new int[100][100];
int arr[] = {1,2,3,4,5};
Arrays.fill(arr,0); //全部赋值为0
Arrays.fill(arr,1,10,0); //从第一个到第十个赋值为0
binarySearch(arr,5); //二分搜索法查找5
binarySearch(arr,1,10,5); //二分搜索法从第一个到第十个查找
newArr = copyOf(arr,10); //复制数组,从0到10
newArr = copyOfRange(arr,1,10); //复制数组,从1到10
sort(arr); //排序
sort(arr,1,10); //从1到10排序
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
ArrayList<Integer> list1 = list;
ArrayList<Integer> list2 = (ArrayList<Integer>) list.clone();
list.set(0,2);
System.out.println(list1.get(0)); //答案为2
System.out.println(list2.get(0)); //答案为1
String类位于java.lang包下
String类作为不可修改的对象,如果用String修改字符串会新建一个String对象,如果频繁修改,则会产生很多String对象,会产生很大的开销,效率也不是很高
提供了字符串的比较,查找,截取,大小写转换等操作
String类被final所修饰,不能被继承
//构造方法
String()构造空串
String(String)构造为String的串
String(Byte[],offset,length) //用byte子数组构造String
String(char[]) //构造一个内容为char[]的字符串
String(char[],offset,count) //取char[]的子数组
//常用方法
String.length() //求长度
String.substring(begin) //从begin处截取字串
String.substring(begin,end) //从[begin,end)处截取字串
String.startwith(String) //是否以该字串开始
String.endwith(String) //是否以该字串结束
String.toString() //返回该字符串本身
String.equals(String) //比较相等
String.equalsIgnoreCase(String) //比较是否相等,忽略大小写
StringBuffer类(StringBuilder类同理,下同)作为可以修改的对象,如果是构造一个需要改变的String的话建议先使用StringBuffer,当String类不需要改变的时候再将其转换到String类
StringBuffer底层维护了一个字符数组,存储字符时实际上时往该字符数组中存储,初始化容量为16,当容量不够用时,自动增长一倍
StringBuffer类也具有String类的方法
//构造方法
string=stringBuffer.toString(); //将stringBuffer类转换为String类
stringBuffer() //空stringBuffer串
stringBuffer(String) //一个内容为String的stringBuffer类
//常用方法
stringBuffer.append(String) //增加到字符串末尾
stringBuffer.append(char)
stringBuffer.length() //返回长度
stringBuffer.replace(start, end, str) //从Start到end区间被str替代
stringBuffer.reverse() //反转形式取代
stringBuffer.insert(i,String) //在i后插入String串
stringBuffer.delete(start,end) //删除[start,end)处的字串
stringBuffer.indexOf(String) //返回字串的第一次索引
stringBuffer.indexOf(String,fromIndex) //返回从fromIndex处开始的第一次索引
stringBuffer.charAt(index) //返回这个索引下的序列值
stringBuffer.setCharAt(index, char) //将下标为index的值修改为char
StringBuffer类所提供的方法都是同步的方法,属于安全的线程操作
StringBuilder类中的大多方法都是异步方法,属于线程安全的操作
如果多线程环境下涉及到大量修改的操作的话,则首先选择StringBuffer
如果非多线程环境下涉及到大量修改的操作的话,则首先选择StringBuilder
总的来说,执行速度的比较 StringBuilder>StringBuffer>String
Java一共有 种数据结构时我们常用的,分别是以下几种
集合类型 | 描述 |
---|---|
ArrayList | 可以动态增长和缩减的序列,类似于C++的vector |
LinkedList | 可以在任何位置高效插入和删除的有序序列,链表 |
ArrayDeque | 实现为循环数组的一个双端队列 |
HashSet | 没有重复元素的无序集合 |
TreeSet | 没有重复元素的有序集合 |
LinkedHashSet | 记住元素插入次序的集合 |
PriorityQueue | 优先队列 |
HashMap | |
TreeMap | |
LinkedHashMap | 记住添加次序的 |
以上所有数据结构都有以下这几种方法,需要记牢
boolean add(E e)
//确保此集合包含指定的元素(可选操作)
boolean addAll(Collection<? extends E> c)
//将指定集合中的所有元素添加到此集合(可选操作)
void clear()
//从此集合中删除所有元素(可选操作)
boolean contains(Object o)
//如果此集合包含指定的元素,则返回 true
boolean containsAll(Collection<?> c)
//如果此集合包含指定 集合中的所有元素,则返回true
boolean equals(Object o)
//将指定的对象与此集合进行比较以获得相等性
int hashCode()
//返回此集合的哈希码值
boolean isEmpty()
//如果此集合不包含元素,则返回 true
Iterator<E> iterator()
//返回此集合中的元素的迭代器
default Stream<E> parallelStream()
//返回可能并行的 Stream与此集合作为其来源
boolean remove(Object o)
//从该集合中删除指定元素的单个实例(如果存在)(可选操作)
boolean removeAll(Collection<?> c)
//删除指定集合中包含的所有此集合的元素(可选操作)
default boolean removeIf(Predicate<? super E> filter)
//删除满足给定谓词的此集合的所有元素
boolean retainAll(Collection<?> c)
//仅保留此集合中包含在指定集合中的元素(可选操作)
int size()
//返回此集合中的元素数
default Spliterator<E> spliterator()
//创建一个Spliterator在这个集合中的元素
default Stream<E> stream()
//返回以此集合作为源的顺序 Stream
Object[] toArray()
//返回一个包含此集合中所有元素的数组
<T> T[] toArray(T[] a)
//返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型
ArrayList list = new ArrayList<>(); //创建一个ArrayList
list.add(1); //向ArrayList中添加元素
list.addAll(list1); //向ArrayList中插入新的ArrayList
try {
list.add(1,2); //将2插入到第一个元素中,第一个元素到最后一个元素依次往后移
list.addAll(1,list1) //将list1中所有元素插入到list的第一个里面
} catch (IndexOutOfBoundsException e) {
//如果第一个数字 > list.size() 则会抛出异常
}
list.get(0); //向ArrayList中获取第0个元素
list.set(0,2); //将第0个元素设置为2
list.clear(); //清空list
boolean b = list.contains(1); //判断list中是否含有1
boolean b = list.isEmpty(); //判断list是否为空
int i = list.indexOf(1); //查询list中第一次出现1的位置下标,没有则返回-1
int i = list.lastIndexOf(1); //查询list中最后出现1的位置下标,没有则返回-1
int x = list.remove(0); //删除第0号元素,同时将第0号元素的值返回
boolean b = list.remove(new Integer(3)); //删除list中第一个出现3的元素
/*
* 当list为Integer类型是,list.remove(0)会被认为删除第0号元素而不是删除第一个出现0的元素
*/
System.out.prinltn(list.size()); //输出list的size大小
LinkedList的操作和ArrayList差不多,这里记录一些ArrayList中没有的一些API
void addFirst(E e)
在该列表开头插入指定的元素
void addLast(E e)
将指定的元素追加到此列表的末尾
boolean contains(Object o)
如果此列表包含指定的元素,则返回 true
Iterator<E> descendingIterator()
以相反的顺序返回此deque中的元素的迭代器
E getFirst()
返回此列表中的第一个元素
E getLast()
返回此列表中的最后一个元素
LinkedList就是链表,ArrayList就是数组
LinkedList插入和删除中间的元素十分方便,但是随机访问的能力很弱
ArrayList插入和删除中间的元素开销大,但是随机访问的能力很强
Stack stack = new Stack<>(); //创建一个新stack
stack.push(1); //将1压入到stack中
int x = stack.peek(); //获取栈顶元素并且不使栈顶元素出栈
int x = stack.pop(); //获取栈顶元素并且使得栈顶元素出栈
int x = stack.search(1); //查找离栈顶元素最近的1离栈顶的位置
eg: 1 2 3 4 5 1 2 3 4 5
stack.search(1); //返回值为3
stack.search(5); //返回值为5
eg: 1 2 3 4 5
stack.search(5); //返回值为-1
boolean empty()
//测试此堆栈是否为空
E peek()
//查看此堆栈顶部的对象,而不从堆栈中删除它
E pop()
//删除此堆栈顶部的对象,并将该对象作为此函数的值返回
E push(E item)
//将项目推送到此堆栈的顶部
int search(Object o)
//返回一个对象在此堆栈上的基于1的位置
set可以先不声明自己的泛型,这样的set可以插入不同的类,如下所示
HashSet s = new HashSet();
s.add("Polaris111");
s.add(123456);
s.add(new BigDecimal(123.456));
System.out.println(s);
打印出来的结果如下所示
Java的set一共分为两类,不能排序HashSet和能够排序的TreeSet,接下来让我分别介绍这两个类
HashSet<String> s = new HashSet<>();
s.add("str1"); //添加
s.add("str2");
s.add("str3");
System.out.println(s.isEmpty()); //判空
System.out.println(s.contains("str1")); //判断集合是否包含元素
System.out.println(s.size()); //集合中元素个数
System.out.println(s.remove("str1")); //删除元素
s.clear(); //清空所有元素
输出结果如下所示
//第一种
Iterator it = s.iterator();
while(it.hasNext()) {
if(it.next().equals("str2")) {
it.remove();
}
}
//第二种
for(String str : s) {
System.out.println(s);
}
TreeSet的内部实现是红黑树,基本操作方式和HashSet相同基本相同
TreeSet<String> s = new TreeSet<>();
s.add("str1"); //添加
s.add("str2");
s.add("str3");
System.out.println(s.isEmpty()); //判空
System.out.println(s.contains("str1")); //判断集合是否包含元素
System.out.println(s.size()); //集合中元素个数
System.out.println(s.remove("str1")); //删除元素
s.clear(); //清空所有元素
输出结果如下所示
//第一种
Iterator it = s.iterator();
while(it.hasNext()) {
if(it.next().equals("str2")) {
it.remove();
}
}
//第二种
for(String str : s) {
System.out.println(s);
}
HashMap<Integer, String> hashMap = new HashMap<>(); //创建元素
hashMap.put(1, "test1"); //插入元素
hashMap.put(2, "test2");
hashMap.put(3, "test3");
System.out.println(hashMap.get(1)); //取元素
System.out.println(hashMap.isEmpty()); //判空
System.out.println(hashMap.size()); //输出元素数量
//判断键是否存在
if(hashMap.containsKey(1)) {
System.out.println("1存在");
}
//判断值是否存在
if(hashMap.containsValue("test1")) {
System.out.println("test1存在");
}
hashMap.remove(1); //删除Key为1的元素
hashMap.remove(2,"test2"); //删除Key为2且值为test2的元素
hashMap.replace(3, "test4"); //将Key为3的元素的Value替换为"test4"
hashMap.replace(3, "test4", "test5"); //将Key为3且Value为"test4"的值替换为"test5"
Set<Map.Entry<Integer, String>> set = hashMap.entrySet(); //获取键
Iterator iterator = set.iterator();
while(iterator.hasNext()) {
Map.Entry<Integer, String> it = (Entry<Integer, String>) iterator.next();
System.out.println(it.getKey()); //取键
System.out.println(it.getValue()); //取值
System.out.println(it.setValue("null")); //重新设置值
}
TreeMap的操作与HashMap差不多,这里我写几个TreeMap特有的操作
TreeMap<Integer, String> treeMap = new TreeMap<>(); //创建元素
treeMap.put(1, "test1"); //插入元素
treeMap.put(2, "test2");
treeMap.put(3, "test3");
Integer integer = treeMap.ceilingKey(3); // 返回大于或等于给定键的键,如果没有此键,则返回null
System.out.println(integer);
Map.Entry<Integer, String> entry = treeMap.ceilingEntry(3); // 返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则返回null
System.out.println(entry.getKey()); //取键
System.out.println(entry.getValue()); //取值
TreeMap在寻找值除了上述的操作外还有以下的操作:
Map.Entry<K,V> ceilingEntry(K key)
//返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则 null
K ceilingKey(K key)
//返回大于或等于给定键的 null键,如果没有此键,则返回 null
Map.Entry<K,V> firstEntry()
//返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null
K firstKey()
//返回此地图中当前的第一个(最低)键
Map.Entry<K,V> floorEntry(K key)
//返回与小于或等于给定键的最大键相关联的键值映射,如果没有此键,则 null
K floorKey(K key)
//返回小于或等于给定键的最大键,如果没有这样的键,则返回 null
SortedMap<K,V> headMap(K toKey)
//返回此地图部分的视图,其密钥严格小于 toKey
NavigableMap<K,V> headMap(K toKey, boolean inclusive)
//返回此地图部分的视图,其键值小于(或等于,如果 inclusive为真) toKey
Map.Entry<K,V> higherEntry(K key)
//返回与最小密钥相关联的密钥值映射严格大于给定密钥,如果没有这样的密钥则 null
K higherKey(K key)
//返回严格大于给定键的最小键,如果没有这样的键,则返回 null
Map.Entry<K,V> lastEntry()
//返回与该地图中最大关键字关联的键值映射,如果地图为空,则返回 null
K lastKey()
//返回当前在此地图中的最后(最高)键
Map.Entry<K,V> lowerEntry(K key)
//返回与最大密钥相关联的密钥值映射严格小于给定密钥,如果没有这样的密钥,则 null
K lowerKey(K key)
//返回严格小于给定键的最大键,如果没有这样的键,则返回 null
Map.Entry<K,V> pollFirstEntry()
//删除并返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null
Map.Entry<K,V> pollLastEntry()
//删除并返回与该地图中最大密钥相关联的键值映射,如果地图为空,则返回 null
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
//返回此地图部分的视图,其关键范围为 fromKey至 toKey
SortedMap<K,V> subMap(K fromKey, K toKey)
//返回此地图部分的视图,其关键字范围从 fromKey (含)到 toKey ,独占
SortedMap<K,V> tailMap(K fromKey)
//返回此地图部分的视图,其键大于等于 fromKey
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
//返回此地图部分的视图,其键大于(或等于,如果 inclusive为真) fromKey
PriorityQueue默认小根堆,要想生成大根堆,可以按照如下方式生成。
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((x,y) -> (y-x));
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.offer(1); //插入元素
priorityQueue.offer(2);
priorityQueue.offer(3);
priorityQueue.offer(4);
priorityQueue.offer(5);
System.out.println(priorityQueue.poll()); //查找队头并删除队头
System.out.println(priorityQueue.peek()); //查找队头
System.out.println(priorityQueue.size()); //输出元素数量
priorityQueue.remove(4); //删除元素如果存在
HashSet可以自定义排序函数,也可以让HashSet排序的类里面重载compareTo函数,操作如下所示
public int compare(String o1, String o2):比较其两个参数的顺序
static class MyClass {
public int f;
public int s;
}
static class MyComparator implements Comparator<MyClass> {
@Override
public int compare(MyClass o1, MyClass o2) {
if(o1.f != o2.f) {
if(o1.f > o2.f) {
return 1;
} else {
return -1;
}
} else {
if(o1.s > o2.s) {
return 1;
} else {
return -1;
}
}
}
}
两个对象比较的结果有三种:大于,等于,小于
如果要按照升序排序,
则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
如果要按照降序排序
则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
做如下测试,可以看到TreeSet按照我们给提供的接口去进行排序的
TreeSet<MyClass> treeSet = new TreeSet<>(new MyComparator());
treeSet.add(new MyClass(1, 2));
treeSet.add(new MyClass(2, 2));
treeSet.add(new MyClass(2, 3));
treeSet.add(new MyClass(4, 3));
treeSet.add(new MyClass(5, 6));
treeSet.add(new MyClass(7, 3));
Iterator it = treeSet.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
也可以在声明类的时候继承Comparable接口来自定义排序方法,这样TreeSet这种排序集合在排序的时候就会执行我们自定义类中的方法
static class MyClass implements Comparable<MyClass> {
public int f;
public int s;
@Override
public int compareTo(MyClass o) {
if(this.f != o.f) {
if(this.f > o.f) {
return 1;
} else {
return -1;
}
} else {
if(this.s > o.s) {
return 1;
} else {
return -1;
}
}
}
}
同样是进行和上面一样的测试,可以发现结果是一样的,TreeSet这种排序集合在排序的时候就会执行类中的compareTo方法
TreeSet<MyClass> treeSet = new TreeSet<>();
treeSet.add(new MyClass(1, 2));
treeSet.add(new MyClass(2, 2));
treeSet.add(new MyClass(2, 3));
treeSet.add(new MyClass(4, 3));
treeSet.add(new MyClass(5, 6));
treeSet.add(new MyClass(7, 3));
Iterator it = treeSet.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
结果如下所示
如果二者都不定义直接排序呢?答案是不可以的,编译器会报如下的错误:
大数类一共有两个,分别是BigInteger和BigDecimal,大数整形变量以及大数浮点数,理论上可以存储无线长的数字(只要你计算机的内存足够),接下来我将会分别介绍这两个类。
BigInteger一共有六个构造方法,分别是以下六个,个人认为最常用的应该是第五个将字符串转换为BigInteger。
BigInteger b = BigInteger(byte[] val)
//将包含BigInteger的二进制补码二进制表达式的字节数组转换为BigInteger。
BigInteger b = BigInteger(int signum, byte[] magnitude)
//将BigInteger的符号大小表示形式转换为BigInteger。
BigInteger b = BigInteger(int bitLength, int certainty, Random rnd)
//构造一个随机生成的正BigInteger,它可能是素数,具有指定的bitLength。
BigInteger b = BigInteger(int numBits, Random rnd)
//构造一个随机生成的BigInteger,均匀分布在0到(2 numBits - 1)的范围内。
BigInteger b = BigInteger(String val)
//将BigInteger的十进制字符串表示形式转换为BigInteger。
BigInteger b = BigInteger(String val, int radix)
//将指定基数中的BigInteger的String表示形式转换为BigInteger。
BigInteger类是可以直接读入的,当然你也可以选择先读入字符串然后再转到BigInteger。
Scanner s = new Scanner(System.in);
while (sc.hasNextBigInteger()) {
BigInteger b = s.nextBigInteger(); //读取BigInteger
BigInteger类是可以直接输出的
System.out.println(b);
BigInteger的四则运算不能用基础的四个符号进行操作,而是需要用BigInteger的方法来实现。
BigInteger b1 = new BigInteger("1000000");
BigInteger b2 = new BigInteger("-2000000");
System.out.println(b2.add(b1)); //加
System.out.println(b2.subtract(b1)); //减
System.out.println(b2.multiply(b1)); //乘
System.out.println(b2.divide(b1)); //除
System.out.println(b2.remainder(b1)); //取余
System.out.println(b2.negate()); //取负号
System.out.println(b2.equals(b1)); //判断相等
System.out.println(b2.gcd(b1)); //求最大公约数
System.out.println(b2.max(b1)); //求最大值
System.out.println(b2.min(b1)); //求最小值
System.out.println(b2.pow(100000)); //开方
System.out.println(b2.and(b1)); //并
System.out.println(b2.not()); //取反
System.out.println(b2.or(b1)); //或
System.out.println(b2.xor(b1)); //异或
BigInteger 的方法如下所示(注意不是静态方法)
BigInteger abs()
//返回一个BigInteger,它的值是此BigInteger的绝对值。
BigInteger add(BigInteger val)
//返回值为 (this + val) 。
BigInteger and(BigInteger val)
//返回值为 (this & val) 。
BigInteger andNot(BigInteger val)
//返回值为 (this & ~val) 。
int bitCount()
//返回与其符号位不同的BigInteger的二进制补码表示中的位数。
int bitLength()
//返回此BigInteger的最小二进制补码表示中的位数, 不包括符号位。
byte byteValueExact()
//将此 BigInteger转换为 byte ,检查丢失的信息。
BigInteger clearBit(int n)
//返回一个BigInteger,其值等于此BigInteger,指定的位被清零。
int compareTo(BigInteger val)
//将此BigInteger与指定的BigInteger进行比较。
BigInteger divide(BigInteger val)
//返回值为 (this / val) 。
BigInteger[] divideAndRemainder(BigInteger val)
//返回两个BigInteger的数组,其中包含 (this / val)后跟 (this % val) 。
double doubleValue()
//将此BigInteger转换为 double 。
boolean equals(Object x)
//将此BigInteger与指定的对象进行比较以实现相等。
BigInteger flipBit(int n)
//返回一个BigInteger,其值等于此BigInteger,指定的位被翻转。
float floatValue()
//将此BigInteger转换为 float 。
BigInteger gcd(BigInteger val)
//返回一个BigInteger,其值是 abs(this)和 abs(val) 。
int getLowestSetBit()
//返回此BigInteger中最右(最低位)一位的索引(最右边一位右侧的零位数)。
int hashCode()
//返回此BigInteger的哈希码。
int intValue()
//将此BigInteger转换为 int 。
int intValueExact()
//将此 BigInteger转换为 int ,检查丢失的信息。
boolean isProbablePrime(int certainty)
//返回 true如果这个BigInteger可能是素数, false如果它是绝对复合。
long longValue()
//将此BigInteger转换为 long 。
long longValueExact()
//将此 BigInteger转换为 long ,检查丢失的信息。
BigInteger max(BigInteger val)
//返回此BigInteger和 val 。
BigInteger min(BigInteger val)
//返回此BigInteger和 val 。
BigInteger mod(BigInteger m)
//返回值为 (this mod m )。
BigInteger modInverse(BigInteger m)
//返回值为 (this -1 mod m) 。
BigInteger modPow(BigInteger exponent, BigInteger m)
//返回值为 (thisexponent mod m)的BigInteger 。
BigInteger multiply(BigInteger val)
//返回值为 (this * val) 。
BigInteger negate()
//返回值为 (-this) 。
BigInteger nextProbablePrime()
//返回大于这个 BigInteger为 BigInteger的第一个整数。
BigInteger not()
//返回值为 (~this) 。
BigInteger or(BigInteger val)
//返回值为 (this | val) 。
BigInteger pow(int exponent)
//返回值为 (thisexponent)的BigInteger 。
static BigInteger probablePrime(int bitLength, Random rnd)
//返回一个正的BigInteger,它可能是素数,具有指定的位长度。
BigInteger remainder(BigInteger val)
//返回值为 (this % val) 。
BigInteger setBit(int n)
//返回一个BigInteger,其值等于具有指定位集合的BigInteger。
BigInteger shiftLeft(int n)
//返回值为 (this << n) 。
BigInteger shiftRight(int n)
//返回值为 (this >> n) 。
short shortValueExact()
//将此 BigInteger转换为 short ,检查丢失的信息。
int signum()
//返回此BigInteger的signum函数。
BigInteger subtract(BigInteger val)
//返回值为 (this - val) 。
boolean testBit(int n)
//返回 true当且仅当指定的位被设置。
byte[] toByteArray()
//返回一个包含此BigInteger的二进制补码表示的字节数组。
String toString()
//返回此BigInteger的十进制字符串表示形式。
String toString(int radix)
//返回给定基数中BigInteger的String表示形式。
static BigInteger valueOf(long val)
//返回一个BigInteger,其值等于指定的 long 。
BigInteger xor(BigInteger val)
//返回值为 (this ^ val) 。
BigDecimal一共有十六个构造方法,分别是以下十六个,同样最常用的方法我认为还是传入字符串
BigDecimal(BigInteger val)
//将 BigInteger转换成 BigDecimal 。
BigDecimal(BigInteger unscaledVal, int scale)
//将BigInteger的 BigInteger值和 int等级转换为 BigDecimal 。
BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)
//将 BigInteger未缩放值和 int扩展转换为 BigDecimal ,根据上下文设置进行舍入。
BigDecimal(BigInteger val, MathContext mc)
//根据上下文设置将 BigInteger转换为 BigDecimal舍入。
BigDecimal(char[] in)
//一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造。
BigDecimal(char[] in, int offset, int len)
//一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造,同时允许一个子阵列被指定。
BigDecimal(char[] in, int offset, int len, MathContext mc)
//一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造,同时允许指定一个子阵列和用根据上下文设置进行舍入。
BigDecimal(char[] in, MathContext mc)
//一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受相同的字符序列作为 BigDecimal(String)构造与根据上下文设置进行舍入。
BigDecimal(double val)
//将 double转换为 BigDecimal ,这是 double的二进制浮点值的精确十进制表示。
BigDecimal(double val, MathContext mc)
//将 double转换为 BigDecimal ,根据上下文设置进行舍入。
BigDecimal(int val)
//将 int成 BigDecimal 。
BigDecimal(int val, MathContext mc)
//将 int转换为 BigDecimal ,根据上下文设置进行舍入。
BigDecimal(long val)
//将 long成 BigDecimal 。
BigDecimal(long val, MathContext mc)
//将 long转换为 BigDecimal ,根据上下文设置进行舍入。
BigDecimal(String val)
//将BigDecimal的字符串表示 BigDecimal转换为 BigDecimal 。
BigDecimal(String val, MathContext mc)
//一个转换的字符串表示 BigDecimal成 BigDecimal ,接受相同的字符串作为 BigDecimal(String)构造,利用根据上下文设置进行舍入。
注意:
上面的那些是我从JavaAPI上面得来的,但是以下这一点一定要注意!
最好使用String来传参构造,而不用double,原因如下
请看下列代码
BigDecimal b1 =new BigDecimal(0.1);
System.out.println(b1);
BigDecimal b2 =new BigDecimal("0.1");
System.out.println(b2);
最后的结果为:
为什么会这样呢?
double构造的结果具有一定的不可预知性,因为由于二进制的原因0.1并没有办法很好的表示,二传入String的构造结果是完全可信的,也就是会正好的得到想要的0.1,所以我们构造BigDecimal的值时最好使用String来构造。
BigDecimal类是可以直接读入的,当然你也可以选择先读入字符串然后再转到BigDecimal。
Scanner s = new Scanner(System.in);
while (sc.hasNextBigDecimal()) {
BigDecimal b = s.nextBigDecimal(); //读取BigInteger
}
BigDecimalr类是可以直接输出的
System.out.println(b);
BigDecimal的四则运算不能用基础的四个符号进行操作,而是需要用BigDecimal的方法来实现。
BigDecimal b1 =new BigDecimal(0.1);
BigDecimal b2 =new BigDecimal("0.2");
System.out.println(b2.add(b1)); //加
System.out.println(b2.subtract(b1)); //减
System.out.println(b2.multiply(b1)); //乘
System.out.println(b2.divide(b1)); //除
System.out.println(b2.remainder(b1)); //取余
System.out.println(b2.negate()); //取负号
System.out.println(b2.equals(b1)); //判断相等
System.out.println(b2.compareTo(b1)); //比大小(比得过是1,相等是0,比不过是-1)
System.out.println(b2.gcd(b1)); //求最大公约数
System.out.println(b2.max(b1)); //求最大值
System.out.println(b2.min(b1)); //求最小值
System.out.println(b2.pow(100000)); //开方
BigDecimal的方法如下所示(注意不是静态方法)
BigDecimal abs()
//返回一个 BigDecimal ,其值为此 BigDecimal的绝对值,其缩放比例为 this.scale() 。
BigDecimal abs(MathContext mc)
//返回一个 BigDecimal ,其值为此 BigDecimal的绝对值,根据上下文设置进行舍入。
BigDecimal add(BigDecimal augend)
//返回 BigDecimal ,其值是 (this + augend) ,其标为 max(this.scale(), augend.scale()) 。
BigDecimal add(BigDecimal augend, MathContext mc)
//返回 BigDecimal ,其值是 (this + augend) ,根据上下文设置进行舍入。
byte byteValueExact()
//将此 BigDecimal转换为 byte ,检查丢失的信息。
int compareTo(BigDecimal val)
//将此 BigDecimal与指定的BigDecimal进行 BigDecimal 。
BigDecimal divide(BigDecimal divisor)
//返回BigDecimal ,其值为(this / divisor) ,优先级为(this.scale() - divisor.scale()) ; 如果不能表示确切的商(因为它具有非终止的十进制扩展),则抛出一个ArithmeticException 。
BigDecimal divide(BigDecimal divisor, int roundingMode)
//返回 BigDecimal ,其值是 (this / divisor) ,其标为 this.scale() 。
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
//返回一个 BigDecimal ,其值为 (this / divisor) ,其比例为指定。
BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
//返回一个 BigDecimal ,其值为 (this / divisor) ,其比例为指定。
BigDecimal divide(BigDecimal divisor, MathContext mc)
//返回 BigDecimal ,其值是 (this / divisor) ,根据上下文设置进行舍入。
BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode)
//返回 BigDecimal ,其值是 (this / divisor) ,其标为 this.scale() 。
BigDecimal[] divideAndRemainder(BigDecimal divisor)
//返回一个两元件 BigDecimal阵列含有的结果 divideToIntegralValue接着的结果 remainder上的两个操作数。
BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc)
//返回一个两元件 BigDecimal阵列含有的结果 divideToIntegralValue接着的结果 remainder上与根据上下文设置进行舍入计算出的两个操作数。
BigDecimal divideToIntegralValue(BigDecimal divisor)
//返回一个 BigDecimal ,它的值是 BigDecimal的整数部分 (this / divisor)取整。
BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc)
//返回值为 BigDecimal的整数部分的 (this / divisor) 。
double doubleValue()
//将此 BigDecimal转换为 double 。
boolean equals(Object x)
//将此 BigDecimal与指定的 Object进行比较以获得相等性。
float floatValue()
//将此 BigDecimal转换为 float 。
int hashCode()
//返回此 BigDecimal的哈希码。
int intValue()
//将此 BigDecimal转换为 int 。
int intValueExact()
//将此 BigDecimal转换为 int ,检查丢失的信息。
long longValue()
//将此 BigDecimal转换为 long 。
long longValueExact()
//将此 BigDecimal转换为 long ,检查丢失的信息。
BigDecimal max(BigDecimal val)
//返回此 BigDecimal和 val 。
BigDecimal min(BigDecimal val)
//返回此 BigDecimal和 val 。
BigDecimal movePointLeft(int n)
//返回一个 BigDecimal ,相当于这个小数点,向左移动了 n个地方。
BigDecimal movePointRight(int n)
//返回一个 BigDecimal ,相当于这个小数点移动了 n个地方。
BigDecimal multiply(BigDecimal multiplicand)
//返回 BigDecimal ,其值是 (this × multiplicand),其标为 (this.scale() + multiplicand.scale()) 。
BigDecimal multiply(BigDecimal multiplicand, MathContext mc)
//返回 BigDecimal ,其值是 (this × multiplicand),根据上下文设置进行舍入。
BigDecimal negate()
//返回 BigDecimal ,其值是 (-this) ,其标为 this.scale() 。
BigDecimal negate(MathContext mc)
//返回 BigDecimal ,其值是 (-this) ,根据上下文设置进行舍入。
BigDecimal plus()
//返回 BigDecimal ,其值是 (+this) ,其标为 this.scale() 。
BigDecimal plus(MathContext mc)
//返回 BigDecimal ,其值是 (+this) ,根据上下文设置进行舍入。
BigDecimal pow(int n)
//返回 BigDecimal ,其值是 (thisn),该电源,准确计算,使其具有无限精度。
BigDecimal pow(int n, MathContext mc)
//返回 BigDecimal ,其值是 (thisn)。
int precision()
//返回此 BigDecimal的 BigDecimal 。
BigDecimal remainder(BigDecimal divisor)
//返回 BigDecimal ,其值是 (this % divisor) 。
BigDecimal remainder(BigDecimal divisor, MathContext mc)
//返回 BigDecimal ,其值是 (this % divisor) ,根据上下文设置进行舍入。
BigDecimal round(MathContext mc)
//返回 BigDecimal根据四舍五入 MathContext设置。
int scale()
//返回此 规模 BigDecimal 。
BigDecimal scaleByPowerOfTen(int n)
//返回一个BigDecimal,其数值等于( this * 10 n )。
BigDecimal setScale(int newScale)
//返回一个 BigDecimal ,其大小是指定值,其值在数字上等于此 BigDecimal 。
BigDecimal setScale(int newScale, int roundingMode)
//返回一个 BigDecimal ,其规模是指定值,其缩放值通过将此 BigDecimal的非标度值乘以10的适当功率来确定,以维持其总体值。
BigDecimal setScale(int newScale, RoundingMode roundingMode)
//返回一个 BigDecimal ,其规模是指定值,其缩放值通过将该 BigDecimal的非标度值乘以10的适当功率来确定,以维持其整体值。
short shortValueExact()
//将此 BigDecimal转换为 short ,检查丢失的信息。
int signum()
//返回这个 BigDecimal的signum函数。
BigDecimal stripTrailingZeros()
//返回一个 BigDecimal ,它在数字上等于此值, BigDecimal表示中删除任何尾随的零。
BigDecimal subtract(BigDecimal subtrahend)
//返回 BigDecimal ,其值是 (this - subtrahend) ,其标为 max(this.scale(), subtrahend.scale()) 。
BigDecimal subtract(BigDecimal subtrahend, MathContext mc)
//返回 BigDecimal ,其值是 (this - subtrahend) ,根据上下文设置进行舍入。
BigInteger toBigInteger()
//将此 BigDecimal转换为 BigInteger 。
BigInteger toBigIntegerExact()
//将此 BigDecimal转换为 BigInteger ,检查丢失的信息。
String toEngineeringString()
//如果需要指数,则使用工程符号返回此 BigDecimal的字符串表示形式。
String toPlainString()
//返回没有指数字段的此 BigDecimal的字符串表示形式。
String toString()
//返回此 BigDecimal的字符串表示,如果需要指数,则使用科学计数法。
BigDecimal ulp()
//返回此 BigDecimal的最后一个位置的ulp(一个单位)的大小。
BigInteger unscaledValue()
//返回一个 BigInteger ,其值是此 BigDecimal的 未缩放值 。
static BigDecimal valueOf(double val)
//转换一个 double成 BigDecimal ,使用 double通过所提供的规范的字符串表示 Double.toString(double)方法。
static BigDecimal valueOf(long val)
//将 long值转换为 BigDecimal ,比例为零。
static BigDecimal valueOf(long unscaledVal, int scale)
//将 long值和 int比例转换为 BigDecimal 。
Calendar
类是一个抽象类,可以为在某一特定时刻和一组之间的转换的方法如YEAR
, MONTH
, DAY_OF_MONTH
, HOUR
,等等,以及用于操纵该日历字段,如获取的日期下个星期。 时间上的瞬间可以用毫秒值表示,该值是从1970年1月1日00:00 00:00.000 GMT(Gregorian)的偏移量。
Calendar的基本使用方法如下所示:
Calendar c = Calendar.getInstance(); //生成一个新的Calendar类
c.set(2022, 3, 24, 10, 10, 10); //set(int year, int month, int date, int hourOfDay, int minute, int second)
cal.set(Calendar.YEAR, 2022); //set(int field, int value) 将给定的日历字段设置为给定的值
System.out.println(c.get(Calendar.YEAR)); //输出当前年
System.out.println(c.get(Calendar.MONTH)); //输出当前月
System.out.println(c.get(Calendar.DATE)); //输出当前日
System.out.println(c.get(Calendar.DAY_OF_WEEK)); //输出当前的星期
System.out.println(c.get(Calendar.HOUR_OF_DAY)); //输出当前小时
System.out.println(c.get(Calendar.MINUTE)); //输出当前分钟
System.out.println(c.get(Calendar.SECOND)); //输出当前秒数
System.out.println(c.getTimeInMillis()); //输出当前时间戳
System.out.println(c.getTime()); //输出的是一个Date对象,表示当前的日期
如果我们相对当前生成的Calendar类进行一个日期的加或减,那么我们可以有以下的两种操作方法
c.setTimeInMillis(1L); //设置时间戳
c.add(Calendar.MINUTE, 1); //add(int field, int amount) 根据日历的规则,将指定的时间量添加或减去给定的日历字段。
//add的值可以为负数
cal.set(Calendar.YEAR, 2022); //set(int field, int value) 将给定的日历字段设置为给定的值
Calendar的set和get常用的字段有:
static int AM
AM字段表示12小时制的当前小时
static int AM_PM
AM_PM字段表示24小时制的当前小时
static int DATE
DATE字段编号表示该月的日期。
static int DAY_OF_MONTH
get字段编号和 set本月的日期。
static int DAY_OF_WEEK
get字段编号和 set表示一周中的日期。
static int DAY_OF_WEEK_IN_MONTH
get字段编号和 set当月的 set几的序号。
static int DAY_OF_YEAR
get和 set字段编号, set本年度的日数。
static int HOUR
get和 set字段编号, get上午或下午的小时。
static int HOUR_OF_DAY
get字段编号和 set当天的小时数。
static int MILLISECOND
get和 set字段号表示 get内的 set数。
static int MINUTE
get和 set字段编号表示小时内的分钟。
static int MONDAY
DAY_OF_WEEK字段的值表示星期一。
static int MONTH
get和 set字段号表示月份。
static int PM
AM_PM字段的值表示从中午到午夜之前的一天中的一段时间。
static int SATURDAY
DAY_OF_WEEK字段的值表示星期六。
static int SECOND
get和 set字段编号表示分钟内的第二个。
static int SEPTEMBER
MONTH字段的值代表了 公历和朱利安日历中的第九个月。
protected long time
这个日历的当前设定时间,以1970年1月1日,格林尼治标准时间0:00:00之后的毫秒表示。
static int WEEK_OF_MONTH
get和 set字段编号, set当月的周数。
static int WEEK_OF_YEAR
get和 set字段编号, set本年度的周数。
static int YEAR
get现场编号和 set表示年份。
月份不是从1开始,而是从0开始的,也就是说1月的表示数字为0
星期日表示的数字为1,星期六的表示数字为7
Calendar c = Calendar.getInstance();
c.set(2022, 2, 27, 10, 10, 10);
System.out.println(c.get(Calendar.DAY_OF_WEEK));
System.out.println(c.getTime());
Calendar c = Calendar.getInstance();
c.set(2022, 2, 27, 10, 10, 10);
System.out.println(c.get(Calendar.DAY_OF_WEEK));
System.out.println(c.getTime());
设置时间戳的时候如果想得到中国的时间(就是你要用的)那么就要减掉8个小时,具体为什么我也不知道。
Calendar c = Calendar.getInstance();
c.setTimeInMillis(0L);
System.out.println(c.getTime());
有了Calendar这个类,我们做一些日期处理的题的时候就会十分顺利,下面引入一道真题,如下所示:
真题链接
import java.util.Calendar;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
long t = s.nextLong();
long offset = 8 * 60 * 60 * 1000; //这里要减掉8个小时
t -= offset;
Calendar c = Calendar.getInstance();
c.setTimeInMillis(t);
System.out.printf("%02d:%02d:%02d\n",c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND));
}
}
代码提示和自动补全
对于编程人员来说,要记住大量的类名或类方法的名字,着实不是一件容易的事情。如果要IDE能够自动补全代码,那将为我们编程人员带来很大帮助。
eclipse代码里面的代码提示功能默认是关闭的,只有输入“.”的时候才会提示功能,下面说一下如何修改eclipse配置:
开启代码自动提示功能打开 Window -> Perferences -> Java ->Editor -> Content Assist,在右边最下面一栏找到 auto-Activation ,下面有三个选项,找到第二个“Auto activation triggers for Java:”选项在其后的文本框中会看到一个“.”存在。这表示:只有输入“.”之后才会有代码提示和自动补全,我们要修改的地方就是这。把该文本框中的“.”换掉,换成“abcdefghijklmnopqrstuvwxyz.”,这样,你在Eclipse里面写Java代码就可以做到按“abcdefghijklmnopqrstuvwxyz.”中的任意一个字符都会有代码提示。
1.第一步:window-> Perferences-> General->WorkPlace -> build :勾选Save automatically before manual build
2.第二步:window-> Perferences->Run/Debug -> Launching:在Save required dirty…下勾选always
注:ctrl和2同时按完以后释放,再快速按L。不能同时按!
这也是个节省时间的法宝。这个组合将当前行的内容往上或下移动。
大显示屏幕能够提高工作效率是大家都知道的。Ctrl+m是编辑器窗口最大化的快捷键。
ctrl+.将光标移动至当前文件中的下一个报错处或警告处。这组快捷键我一般与ctrl+1一并使用,即修改建议的快捷键。
5.代码助手:Ctrl+Space(简体中文操作系统是Alt+/)
6.Ctrl+D: 删除当前行
7.Ctrl+shift+F:格式化当前代码
8.Alt+Shift+Z:包裹选中的代码
syso 加内容辅助快捷键:alt+/,System.out.println();
for或者foreach 加内容辅助快捷键:alt+/,快速构建for循环
main:加内容辅助快捷键:alt+/,快速构建主函数
注意:
除了使用alt+‘/’, Eclipse默认还提供了很多代码模板。打开 Windows->Preferences->Java->Editor->Templates,可以看到所有已定义的代码模板列表。
F5 单步跳入
F6 单步跳过
F7 单步返回
F8 继续
Ctrl+Shift+D 显示变量的值
Ctrl+Shift+B 在当前行设置或者去掉断点
Ctrl+R 运行至行(超好用,可以节省好多的断点)