BigInteger类型的数字范围较Integer,Long类型的数字范围要大得多,它支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值而不会丢失任何信息。
构造方法
//进制转换
@Test
public void testScale() {
//在构造将函数时,把radix进制的字符串转化为BigInteger
String str = "1011100111";
int radix = 2;
BigInteger interNum1 = new BigInteger(str,radix); //743
//我们通常不写,则是默认成10进制转换,如下:
BigInteger interNum2 = new BigInteger(str); //1011100111
}
读入方法
//读入方法:nextBigInteger()
@Test
public void test5() {
Scanner scan = new Scanner(System.in); // 读入
int n = scan.nextInt(); // 读入一个int;
BigInteger m = scan.nextBigInteger(); // 读入一个BigInteger;
while(scan.hasNext()){
System.out.print("scan.hasNext()=" + scan.hasNext());
}
}
运算与比较
//基本运算:add(),subtract(),multiply(),divide(),mod(),remainder(),pow(),abs(),negate()
@Test
public void testBasic() {
BigInteger a = new BigInteger("13");
BigInteger b = new BigInteger("4");
int n = 3;
//1.加
BigInteger bigNum1 = a.add(b); //17
//2.减
BigInteger bigNum2 = a.subtract(b); //9
//3.乘
BigInteger bigNum3 = a.multiply(b); //52
//4.除
BigInteger bigNum4 = a.divide(b); //3
//5.取模(需 b > 0,否则出现异常:ArithmeticException("BigInteger: modulus not positive"))
BigInteger bigNum5 = a.mod(b); //1
//6.求余
BigInteger bigNum6 = a.remainder(b); //1
//7.平方(需 n >= 0,否则出现异常:ArithmeticException("Negative exponent"))
BigInteger bigNum7 = a.pow(n); //2197
//8.取绝对值
BigInteger bigNum8 = a.abs(); //13
//9.取相反数
BigInteger bigNum9 = a.negate(); //-13
}
//比较大小:compareTo(),max(),min()
@Test
public void testCompare() {
BigInteger bigNum1 = new BigInteger("52");
BigInteger bigNum2 = new BigInteger("27");
//1.compareTo():返回一个int型数据(1 大于; 0 等于; -1 小于)
int num = bigNum1.compareTo(bigNum2); //1
//2.max():直接返回大的那个数,类型为BigInteger
// 原理:return (compareTo(val) > 0 ? this : val);
BigInteger compareMax = bigNum1.max(bigNum2); //52
//3.min():直接返回小的那个数,类型为BigInteger
// 原理:return (compareTo(val) < 0 ? this : val);
BigInteger compareMin = bigNum1.min(bigNum2); //27
}
BigDecimal(int)
创建一个具有参数所指定整数值的对象
BigDecimal(double)
创建一个具有参数所指定双精度值的对象(参数类型为double的构造方法的结果有一定的不可预知性)
BigDecimal(long)
创建一个具有参数所指定长整数值的对象
BigDecimal(String)
创建一个具有参数所指定以字符串表示的数值的对象
运算与比较
add(BigDecimal)
BigDecimal对象中的值相加,返回BigDecimal对象
subtract(BigDecimal)
BigDecimal对象中的值相减,返回BigDecimal对象
multiply(BigDecimal)
BigDecimal对象中的值相乘,返回BigDecimal对象
divide(BigDecimal)
BigDecimal对象中的值相除,返回BigDecimal对象
toString()
将BigDecimal对象中的值转换成字符串
doubleValue()
将BigDecimal对象中的值转换成双精度数
floatValue()
将BigDecimal对象中的值转换成单精度数
longValue()
将BigDecimal对象中的值转换成长整数
intValue()
将BigDecimal对象中的值转换成整数
compareTo()
比较大小
处理小数:setScale()
setScale(1) 表示保留一位小数,默认用四舍五入方式
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入(5则向上入),2.35变成2.4
setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入(5则向下舍),2.35变成2.3
LocalDate以年月日的格式输出,即yyyy-MM-dd。
初始化LocalDate
1. now(): 给出LocalDate实例,该实例包含默认时区的系统时钟的当前日期。
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
/*输出
2021-06-13
*/
2. now(Clock clock): 提供LocalDate实例,该实例具有从指定时钟获得的当前日期。
LocalDate localDate = LocalDate.now(Clock.systemUTC());
3. now(ZoneId zone): 给出当前日期的LocalDate实例,该日期来自指定时区的系统时钟。
LocalDate localDate = LocalDate.now(ZoneId.systemDefault());
4. of(int year, int month, int dayOfMonth: 从给定的年、月、日中获得LocalDate实例,输入数据类型为int。
LocalDate localDate = LocalDate.of(2018, 11, 30);
/*输出
2018-11-30
*/
5. of(int year, Month month, int dayOfMonth): 从给定的年(int)、月(Month)和日(int)给出LocalDate实例。
LocalDate localDate = LocalDate.of(2018, Month.NOVEMBER, 30);
/*输出
2018-11-30
*/
6. ofEpochDay(long epochDay): 从给定的纪元日数中给出LocalDate实例。
LocalDate localDate = LocalDate.ofEpochDay(500);
/*输出
1971-05-16
*/
7. ofInstant(Instant instant, ZoneId zone): 从给定的Instant和ZoneId给出LocalDate实例。(ofInstant在Java 9中被引入)
LocalDate localDate = LocalDate.ofInstant(Instant.now(), ZoneId.systemDefault());
8. ofYearDay(int year, int dayOfYear): 从给定的年份和年份中的天数给出LocalDate实例,输入数据类型为int。
LocalDate localDate = LocalDate.ofYearDay(2018, 02);
/*输出
2018-01-02
(即2018年第二天的日期)
*/
9. parse(CharSequence text): 从给定的文本字符串,如 "2018-10-01",给出LocalDate实例。
LocalDate localDate = LocalDate.parse("2018-10-01");
/*输出
2018-10-01
*/
10. parse(CharSequence text, DateTimeFormatter formatter): 从给定格式的文本字符串中获得LocalDate实例。输出的LocalDate将是yyyy-MM-dd格式。
LocalDate localDate = LocalDate.parse("15-03-2018", DateTimeFormatter.ofPattern("dd-MM-yyyy"));
/*输出
2018-03-15
*/
11. from(TemporalAccessor temporal): 从给定的时间对象中获得LocalDate实例。
LocalDate localDate = LocalDate.from(LocalDate.now());
Arrays.sort(T[] a, Comparator Super T> c)用Comparator接口实现自定义排序规则
List
List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。
Set
Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象。
Map
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
Set和List的区别
1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
2. Set 检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
3. List 和数组类似,可以动态增长,根据实际存储的数据的长度自动增长 List 的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
集合框架的遍历方式
import java.util.*;
public class Test{
public static void main(String[] args) {
List list=new ArrayList();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用 For-Each 遍历 List(增强for)
for (String str : list) { //也可以改写 for(int i=0;i ite=list.iterator();
while(ite.hasNext())//判断下一个元素之后有值
{
System.out.println(ite.next());
}
}
}
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。
以下情况使用 ArrayList :
以下情况使用 LinkedList :
手动实现Array List
import java.util.Arrays;
import java.util.Random;
public class ArrayList {
/**
* 存储当前线性表内容
*/
private Object[] elementData;
/**
* 存储当前线性表长度
*/
private int size;
/**
* 默认的空线性表
*/
private Object[] DEFAULT_EMPTY_ELEMENTDATA = {};
/**
* 定义一个List的最大容量
*/
private int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE - 8;
public ArrayList(int length) {
elementData = new Object[length];
}
/**
* 初始化一个空的ArrayList
*/
public ArrayList() {
elementData = DEFAULT_EMPTY_ELEMENTDATA;
}
private void grow(int minCapacity) {
//现在的数组的长度
int oldCapacity = elementData.length;
//新数组的长度,在现有数组长度的基础上,在增加1/2。这样不至于增加太多,也不至于太少,导致增加次数过多
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新的数组的长度>目前需要的数组长度,则扩大现在需要的数组长度
if (minCapacity > newCapacity) {
newCapacity = minCapacity;
}
//如果新的数组长度大于设定的最大值,则直接去Integer能表示的最大值
if (newCapacity > DEFAULT_MAX_CAPACITY) {
newCapacity = Integer.MAX_VALUE;
}
//通过数组拷贝,将原数组进行扩容。
elementData = Arrays.copyOf(elementData, newCapacity);
}
public void add(Object e) {
if (size >= elementData.length) {
grow(size + 1);
}
elementData[size++] = e;
}
public void add(int index, int element) {
Object[] newElementData = new Object[size + 1];
//将原来数组的index之前的元素复制到新数组
System.arraycopy(elementData, 0, newElementData, 0, index);
//将元素赋值给新数组的第index个元素
newElementData[index] = element;
//将原数组的index之后的元素复制到新数组的index元素之后。
System.arraycopy(elementData, index, newElementData, index + 1, size - index);
//将原来的数组指向新的数组
elementData = newElementData;
size++;
}
public Object get(int index) {
return elementData[index];
}
public int size () {
//返回的是元素的个数,而不是数组的长度,所以只有往List中添加了元素之后,size才会增加
return size;
}
public int indexOf(Object e) {
for (int i = 0; i < size; i++) {
if (e == elementData[i]) {
return i;
}
}
return -1;
}
public boolean contains(Object e) {
for (Object obj : elementData) {
if (e == obj) {
return true;
}
}
return false;
}
public static void main(String[] args) {
ArrayList s = new ArrayList(15);
for(int i=0;i<10;i++){
s.add(i);
System.out.println(s.get(i));
}
s.add(9,100);
System.out.println(s.get(9));
System.out.println(s.size());
System.out.println(s.indexOf(2));
System.out.println(s.indexOf(10));
System.out.println(s.contains(3));
System.out.println(s.contains(20));
}
}