学Java第十三天(至Map)
重点
1.TreeSet的Comparator排序方式
TreeSet的排序方式有2种
1.自然顺序(Comparable)
2.比较器顺序(Comparator)
public TreeSet(Comparator<? super E> comparator)
使用场景:如果元素的类型是final类型,不被重写,这个时候选择Comparator排序方式
3.如果希望有相同的元素存在,在compareTo或者compare方法,返回1就行了。
public class Demo01 {public static void main(String[] args) {Set\<Integer> set = new TreeSet\<Integer>(new MyComparator());set.add(123);set.add(12);set.add(55);set.add(16);for(Integer i : set){System.out.println(i);}}
}class MyComparator implements Comparator\<Integer>{@Overridepublic int compare(Integer o1, Integer o2) {// TODO Auto-generated method stubreturn o2-o1;}
}
2.TreeSet排序原理总结
TreeSet的特点:
–TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
–TreeSet排序方式有两种自然顺序和比较器顺序
自然顺序(Comparable)
TreeSet类的add()方法中会把存入的对象提升为Comparable类型
调用对象的compareTo()方法和集合中的对象比较
根据compareTo()方法返回的结果进行存储比较器顺序(Comparator)
创建TreeSet的时候可以制定 一个Comparator
如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的规则比较
add()方法内部会自动调用Comparator接口中compare()方法排序
调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
–两种比较方式的区别
1.TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
2.TreeSet如果传入Comparator, 就优先按照Comparator
3.Map介绍
Map是属于java.util的一个接口Map<K,V>
类型参数:
K - 映射所维护的键的类型
V - 映射值的类型
Map是将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map接口和Collection接口的不同
–Map是双列的,Collection是单列的
–Map的键唯一,Collection的Set是唯一的,List不是惟一的
Map:有几个常用的子类HashMap,LinkedHashMap,TreeMap,Hashtable,Properites
4.Map的功能
a>添加功能
V put(K key,V value):添加元素。
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
b>删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
c>判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
d>获取功能
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合
e>长度功能
int size():返回集合中的键值对的个数
5.HashMap使用注意事项
- 声明HashMap时的键值可以是任意对象
- 如果有重复的键,会把以前的替换
- 值能为空
- 键能为空,但这样写没什么意义
- put方法的返回值
- 如果键是第一次存储,就直接存储元素,返回null
- 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
6.Map的遍历,有两种方式
a>Map集合的遍历一(键找值)
//1.创建Map对象
Map<String,String> map = new HashMap<String,String>();
map.put(“name”, “刘三姐”);
map.put(“age”, “48”);
map.put(“gender”, “女”);
map.put(“height”, “1.62”);
//3.遍历
//3.1获取map所有键
Set\<String> keys = map.keySet();
//3.2遍历键
for(String key : keys){//3.3 通过key获取值String value = map.get(key);//打印key&valueSystem.out.println(key + " : " + value);
}
b>Map集合的遍历二(键值对对象Entry找键和值)
public static void test1() {
//1.创建Map对象
Map<String,String> map = new HashMap<String,String>();
map.put(“name”, “刘三姐”);
map.put(“age”, “48”);
map.put(“gender”, “女”);
map.put(“height”, “1.62”);
//java.util.Map.Entry
/*** Entry:称为键值对 对象* */
Set\<Entry\<String, String>> entries = map.entrySet();
//遍历
for(Entry\<String, String> entry : entries){String key = entry.getKey();String value = entry.getValue();System.out.println(key + " : " + value);
}
}
7.键值对对象找键和值源码分析
- Map.Entry理解成"键值对对象"
- Map.Entry是一个接口,它的实现类是HashMap$Node
- Map.Entry是有个key和value属性,通过get方法可以取值
- 遍历Entry的两种方法,通过迭代器和for增强
//1.创建Map
Map\<String,Integer> map = new HashMap\<String,Integer>();
map.put("zhangsan", 100);
map.put("lisi", 89);
map.put("wangwu", 1000);//2.遍历
Set\<Entry\<String, Integer>> entries = map.entrySet();//2.1通过增强for循环来遍历Set
/*for(Entry\<String, Integer> entry : entries){//Map.Entry 的实现类HashMap$Node System.out.println(entry.getClass());System.out.println(entry.getKey() + "---" + entry.getValue());
}*///2.2 通过迭代器来遍历Set
Iterator\<Entry\<String, Integer>> iterator = entries.iterator();
while(iterator.hasNext()){Entry\<String, Integer> entry = iterator.next();System.out.println(entry.getKey() + "---" + entry.getValue());
}
8.LinkedHashMap
LinkedHashMap是存和取的顺序是一样
HashMap是存和取的顺序不是一样
LinkedHashMap它是继承HashMap
9.TreeMap
TreeMap会对键key进行排序
TreeMap的key,如果是自定义对象话,这个对象要实现Comparable接口,
或者说在new TreeMap的时候,传一个comparator参数
public class Demo01 {public static void main(String[] args) {// TODO Auto-generated method stub//案例:TreeMap集合键是Student值是String/*** TreeMap对key进行排序*/test3();}//使用Comparator进行TreeMap的key排序public static void test3() {Map\<Student,String> map = new TreeMap\<Student,String>(new Comparator\<Student>() {@Overridepublic int compare(Student o1, Student o2) {// TODO Auto-generated method stub//按名字字母的倒序排序int num = o2.name.compareTo(o1.name);num = num == 0 ? 1 : num;//同名的可以存储return num;}});map.put(new Student("banana", 18), "gz");map.put(new Student("cc", 18), "sz");map.put(new Student("apple", 18), "xg");map.put(new Student("cc", 28), "sz");for(Entry\<Student,String> entry :map.entrySet()){System.out.println(entry.getKey() + " - " + entry.getValue());}}//使用Comparable进行TreeMap的key排序public static void test2() {Map\<Student,String> map = new TreeMap\<Student,String>();map.put(new Student("banana", 18), "gz");map.put(new Student("cc", 18), "sz");map.put(new Student("apple", 18), "xg");map.put(new Student("cc", 28), "sz");for(Entry\<Student,String> entry :map.entrySet()){System.out.println(entry.getKey() + " - " + entry.getValue());}}public static void test1() {Map\<String,String> map = new TreeMap\<String,String>();map.put("zhangsan", "广州");map.put("lisi", "广西");map.put("wangwu", "湖南");map.put("zhaoliu", "湖北");map.put("xiaoqi", "福建");//最方便遍历方式//Set\<Entry\<String, String>> entries = map.entrySet();for(Entry\<String, String> entry : map.entrySet()){System.out.println(entry.getKey() + "--" + entry.getValue());} }
}class Student implements Comparable\<Student>{String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Student o) {// TODO Auto-generated method stub//按名字字母排序int num = this.name.compareTo(o.name);//同名的可以存储num = num == 0 ? 1 : num;return num;}}
10.Collections集合工具类
Collections成员方法
public static <T> void sort(List<T> list) 排序
public static <T> int binarySearch(List<?> list,T key) 二分查找
public static <T> T max(Collection<?> coll) 取大值
public static void reverse(List<?> list) 反转
public static void shuffle(List<?> list) 打乱顺序
public class Demo01 {public static void main(String[] args) {//Collections工具类的概述和常见方法/*** 1.Collection 与 Collections 区别* Collection是一个接口* Collections是一个类* 2.Collections的作用针对集合操作 的工具类* * 3.Collections成员方法public static <T> void sort(List<T> list) 排序public static <T> int binarySearch(List<?> list,T key) 二分查找public static <T> T max(Collection<?> coll)public static void reverse(List<?> list)public static void shuffle(List<?> list)*/List<Integer> list1 = new ArrayList<Integer>();list1.add(23);list1.add(2);list1.add(3);list1.add(13);System.out.println("list1:" + list1);//1.给list集合进行排序//Collections.sort(list1);//System.out.println("list1:" + list1);//2.二分查找//int index = Collections.binarySearch(list1, 13);//System.out.println("13在list1中的位置:" + index);//3.取最大值/*** Collection* -List* -Set*/int max = Collections.max(list1);System.out.println("最大值:" + max);//4.reverse 反转Collections.reverse(list1);System.out.println("反转后的list1" + list1);//5.shuffle 打乱顺序Collections.shuffle(list1);System.out.println("打乱后的list1" + list1);}
}
11.泛型固定下边界 【? super E】
/*泛型固定下边界 ? super E
1.回顾 【? extends E】-表示泛型固定上边界
? 表示子类,E表示父类
ArrayList.addAll(Collection<? extends Person> c)
2.【? super E】 -表示泛型固定下边界
? 表示父类,E表示的是子类
ArrayList.sort(Comparator<? super Student> c)
3.【? extends E 】针对存的操作
4.【? super E】 针对取的操作*/
练习题
1.在一个集合中存储了无序并且重复的字符串,让其有序(字母顺序),而且还不能去除重复
public static void main(String[] args) { Set\<String> set = new TreeSet\<String>(new Comparator\<String>() {@Overridepublic int compare(String o1, String o2) {// TODO Auto-generated method stubint num = o1.compareTo(o2);//由小到大num = num==0 ? 1 : num;//保存同名元素return num;}});set.add("baa");set.add("dbb");set.add("ccc");set.add("ccc");System.out.println(set);for(String str : set){System.out.println(str);}}
}
2.从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印
- 掌握:
- 1.数字的倒序实现
- 2.把str转成int
public class Demo01 {public static void main(String[] args) {//1.创建TreeSet集合Set\<Integer> set = new TreeSet\<Integer>(new Comparator\<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {// TODO Auto-generated method stubreturn o2 - o1;}});//2.接收整数存在TreeSet中System.out.println("请多次输入整数,直到输入quit时结束输入");Scanner scanner = new Scanner(System.in);while (true) {String str = scanner.next();if ("quit".equals(str)) {break;}set.add(Integer.parseInt(str));}//3.打印集合for(Integer i : set){System.out.println(i);}}
}
3.键盘录入学生信息按照总分排序后输出在控制台
/**
* 1.创建学生类
* 添加3个学科(语文,数学,英语)成绩属性
* 添加名字属性
* 在有参构造方法中把总分算好
* 2.把n个学生添加到TreeSet中
* angle,89,98,68
* 3.TreeSet要进行总分排序
* 4.键盘输入学生信息格式:【名字,89,98,68】* 5.当键盘输入quit,代表学生的成绩录入完毕* * 技巧:字符串有个split(",")方法* 这个方法把有固定格式的字符串[angle,89,98,68]解析成数组 [angle, 89, 98, 68]*/
public class Demo01 {public static void main(String[] args) {//1.创建集合Set\<Student> set = new TreeSet\<Student>();//2.添加元素//2.1创建ScannerScanner scanner = new Scanner(System.in);//2.2录入多个学生成绩System.out.println("请录入学生成绩,录入的格式【名字,89,98,68】");System.out.println("如果录入完毕,请输入quit退出");while(true){//2.3 获取录入学生成绩信息//angle,89,98,68String info = scanner.nextLine();System.out.println("info:" + info);//2.4 判断是否录入完毕if(info.equals("quit")){break;}//2.5 解析数据 info = "angle,89,98,68",//把有固定格式的字符串解析成数组 [angle, 89, 98, 68]String[] infos = info.split(",");System.out.println(Arrays.toString(infos));String name = infos[0];String chineseStr = infos[1];String mathStr = infos[2];String englishStr = infos[3];//把内容封装成学生对象Student stu = new Student(name, Integer.parseInt(chineseStr), Integer.parseInt(mathStr), Integer.parseInt(englishStr));//System.out.println(Arrays.toString(infos));//把学生放在Set中set.add(stu);}// set.add(new Student("banana", 89, 89, 91));
// set.add(new Student("angle", 89, 89, 90));
// set.add(new Student("apple", 89, 89, 91));
// set.add(new Student("king", 89, 89, 89));
// set.add(new Student("banana", 89, 89, 91));//3.遍历集合for(Student stu : set){System.out.println(stu);}}
}
public class Student implements Comparable\<Student>{//1.创建学生类,添加3个学科(语文,数学,英语)成绩属性private String name;private int chinese;private int math;private int english;private int totalScore;//总分public Student() {super();// TODO Auto-generated constructor stub}/*** * @param name 学生名字* @param chinese 语文成绩* @param math 数学成绩* @param english 英语成绩*/public Student(String name, int chinese, int math, int english) {super();this.name = name;this.chinese = chinese;this.math = math;this.english = english;//在构造方法中把总分先算好this.totalScore = chinese + math + english;}@Overridepublic String toString() {return "Student [名字=" + name + ", 语文=" + chinese + ", 数学=" + math + ", 英语=" + english+ ", 总分=" + totalScore + "]";}@Overridepublic int compareTo(Student o) {// TODO Auto-generated method stub//总分排序【由大到小】int num = o.totalScore - this.totalScore;//如果总分一样,就按照名字排序num = num == 0 ? this.name.compareTo(o.name) : num;//同名的学生可能有些没法排序num = num == 0 ? 1 : num;return num;}}
4.HashMap集合键是Student,值是String
public class Demo01 {public static void main(String[] args) {/* 案例 :HashMap集合键是Student,值是String键是学生对象,代表每一个学生 值是字符串对象,代表学生归属地注意事项:1.打印的key是student的toString方法返回的字符串2.如果key相同,会把前面的值替换掉,但是必须是同一个对象3.HashMap是无序的4.new出来的都不是相同的key,因为地址不同。如果属性一样,想替换前面对应属性一样的valus时候,需要重写equals&hashcode方法*/Map\<Student,String> map = new HashMap\<Student,String>();map.put(new Student("小刘", 18), "湖北");map.put(new Student("小胡", 18), "湖南");// Student stu = new Student("小官", 18);
// map.put(stu, "广东");
// map.put(stu, "广西");map.put(new Student("小官", 18), "广东");map.put(new Student("小官", 18), "广西");//System.out.println("map:" + map);//遍历Set\<Entry\<Student, String>> entries = map.entrySet();for(Entry\<Student, String> entry : entries){System.out.println(entry.getKey() + " --- " + entry.getValue());}}
}class Student{String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Student other = (Student) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}
5.统计字符串中每个字符出现的次数
public static void main(String[] args) {String str = "aaaabbbccccc";/*** Map\<Character,Integer> map = new HashMap\<Character,Integer>();* map.put('a',4);* map.put('b',3);* map.put('c',5);*///1.创建存储字符次数的Map集合Map\<Character,Integer> map = new HashMap\<Character,Integer>();//2.遍历字符串的每一个字符for(int i=0;i\<str.length();i++){//3.往map里添加字符出现次数(累加)char ch = str.charAt(i);//map第一次出现这个字符if(!map.containsKey(ch)){map.put(ch, 1);}else{//map如果不是第一 次出现这个字符,累加+1map.put(ch, map.get(ch) + 1);}}System.out.println("map:" + map);}
6.集合的嵌套,Map嵌套Set
/*** 掌握: 1.HashMap嵌套HashSet,或者说Map里嵌套Set* 2.集合嵌套的遍历**/
public class Demo01 {public static void main(String[] args) {//集合嵌套之HashMap嵌套HashSet/* 需求一个学校有两个班一个班有多个学生通过HashMap与HashSet来实现数据存储*///1.创建两个班(Set)Set\<Student> javaClass = new HashSet\<Student>();javaClass.add(new Student("小贾", 28));javaClass.add(new Student("小牛", 18));Set\<Student> h5Class = new HashSet\<Student>();h5Class.add(new Student("小丽", 28));h5Class.add(new Student("小红", 18));//2.创建一个学校(Map)//Key:班级名字,Value:这个班所有学生/**** HashMap嵌套HashSet,或者说Map里嵌套Set*/Map\<String,Set\<Student>> school = new HashMap\<String,Set\<Student>>();school.put("Java班级", javaClass);school.put("H5班级", h5Class);//3.遍历//3.1遍历学校里的班级for(Entry\<String,Set\<Student>> entry : school.entrySet()){System.out.println("班级名称:" + entry.getKey());//3.2 遍历班级里学生//Set\<Student> myClass = entry.getValue();for(Student stu : entry.getValue()){System.out.println(stu);}}}
}
class Student{String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}}
7.斗地主
- 功能:
* 1.准备一幅牌(54张)
* 2.洗牌(打乱牌序) shuffle方法
* 3.发牌(三个人)
* 4.留三张底牌
* 5.每个人拿到牌后,对牌进行排序
* 6.出牌…
*
* 一.发牌(每个人的牌先不排序)
* 二.发牌(每个人的牌是排序)
方法一:
public class Demo01 {public static void main(String[] args) {//一.发牌(每个人的牌先不排序)
// * 1.准备一幅牌(54张) 用List<String>List<String> poker = new ArrayList<String>();//花色String[] colors = {"黑桃","红心","梅花","方块"};//牌的数字String[] nums = {"2","3","4","5","6","7","8","9","10","j","Q","K","A"};//遍历for(String color : colors){for(String num : nums){String pai = color + num;//一张牌poker.add(pai);}}//少两个王poker.add("小王");poker.add("大王");System.out.println("poker" + poker);// * 2.洗牌(打乱牌序)Collections.shuffle(poker);System.out.println("poker" + poker);// * 3.随机留三张底牌List<String> dipai = new ArrayList<String>();//底牌Random random = new Random();for(int i=0;i<3;i++){//0~53;//0~52//0~51int index = random.nextInt(poker.size());String pai = poker.remove(index);dipai.add(pai);//System.out.println("底牌:" + pai);}System.out.println("底牌:" + dipai);//抽了3张底牌,还有51张牌
// * 4.发牌(三个人) 把每个人的牌存在List集合List<String> gaojin = new ArrayList<String>();//高进List<String> longwu = new ArrayList<String>();//龙五List<String> me = new ArrayList<String>();//我for(int i=0;i<poker.size();i++){//取牌String pai = poker.get(i);int mod = i % 3;//前3张:索引0,1,2,3if(mod == 0){gaojin.add(pai);}else if(mod == 1){longwu.add(pai);}else if(mod == 2){me.add(pai);}}// * 5.每个人拿到牌后System.out.println("高进:" + gaojin);System.out.println("龙五:" + longwu);System.out.println("我:" + me);}}
方法二:(灵活的运用到了Map、Set、List的属性,发牌后有序)
public class Demo01 {public static void main(String[] args) {// TODO Auto-generated method stub//模拟斗地主/*** 功能:* 1.准备一幅牌(54张)* 2.洗牌(打乱牌序)* 3.发牌(三个人)* 4.留三张底牌* 5.每个人拿到牌后,对牌进行排序* 6.出牌...* * 二.发牌(每个人的牌是排序)*///1.准备一幅牌(54张)Map<Integer,String> poker = new HashMap<Integer,String>();//1.1花色String[] colors = {"黑桃","红心","梅花","方块"};//1.2牌的数字String[] nums = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};//1.3遍历花色&数字int index = 0;//是进行花色排序/*for(String color : colors){for(String num : nums){String pai = color + num;//1.4 把索引和牌 添加到Mappoker.put(index, pai);index ++;//System.out.println(pai);}}*///进行数字排序for(String num : nums){for(String color : colors){String pai = color + num;//1.4 把索引和牌 添加到Mappoker.put(index, pai);index ++;//System.out.println(pai);}}//1.5 添加大王小王poker.put(index, "小王");index++;poker.put(index, "大王");//1.6 遍历pokerSystem.out.println("===========遍历poker=========");for(Entry<Integer,String> entry:poker.entrySet()){System.out.println(entry.getKey() + " -- " + entry.getValue());}//2.洗牌//2.1获取牌的索引//Set<Integer> pokerKeys =poker.keySet();//把set 转 listList<Integer> pokerIndexs = new ArrayList<Integer>();for(Integer i : poker.keySet()){pokerIndexs.add(i);}//2.2把索引打乱Collections.shuffle(pokerIndexs);System.out.println("==========打乱的牌索引==========");System.out.println("pokerIndexs:" + pokerIndexs);//3.留底牌【前三张】Set<Integer> dipaiIdxs = new TreeSet<Integer>();dipaiIdxs.add(pokerIndexs.remove(0));dipaiIdxs.add(pokerIndexs.remove(0));dipaiIdxs.add(pokerIndexs.remove(0));System.out.println("=========底牌索引===========");System.out.println("dipaiIdxs:" + dipaiIdxs);//4.发牌Set<Integer> gaoJinIdxs = new TreeSet<Integer>();Set<Integer> longWuIdxs = new TreeSet<Integer>();Set<Integer> meIdxs = new TreeSet<Integer>();for(int i = 0;i < pokerIndexs.size();i++){//取出扑克的索引int pokerIndex = pokerIndexs.get(i);int mod = i % 3;if(mod == 0){gaoJinIdxs.add(pokerIndex);}else if(mod == 1){longWuIdxs.add(pokerIndex);}else if(mod == 2){meIdxs.add(pokerIndex);}}//5.打印每个人扑克的索引System.out.println("高进:" + gaoJinIdxs);System.out.println("龙五:" + longWuIdxs);System.out.println("我:" + meIdxs);//6.看牌lookPoker("底牌", poker, dipaiIdxs);lookPoker("高进", poker, gaoJinIdxs);lookPoker("龙五", poker, longWuIdxs);lookPoker("我", poker, meIdxs);}//看牌/*** * @param name 玩家的名字* @param poker 完整的扑克牌* @param playerPokerIndexs 玩家扑克牌的索引*/public static void lookPoker(String name,Map<Integer,String> poker,Set<Integer> playerPokerIndexs){List<String> pokerValues = new ArrayList<String>();//遍历玩完的扑克牌索引for(Integer key :playerPokerIndexs){pokerValues.add(poker.get(key));}System.out.println(name + ":" + pokerValues);}}
8.金融借款算法
本金
利息
利率:【1分=1%=0.01】【1厘=0.1%=0.001】
还款日期的计算【看代码】
public class FinanceUtil {/*** 返回 还款日期列表* @param date 借款日期* @param borrowMonth 贷款期数* @return */public static List<String> replyDateList(Date date,int borrowMonth ) {//还款日期计算List<String> list = new ArrayList<String>();//1.借款日期Date borrowDate = new Date();//2.借款期数(借几个月)//3.计算未来12月的还款日期//3.1 把借款日期的年月日算出来 yyyy-MM-ddSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String str = sdf.format(borrowDate);String[] s = str.split("-");//按规律截取字符串int y = Integer.parseInt(s[0]);int m = Integer.parseInt(s[1]);int d = Integer.parseInt(s[2]);/*System.out.println("年:" + y);System.out.println("月:" + m);System.out.println("日:" + d);*///3.2 计算未来还款日期//i = 0,1,2,3,4,5,6,7,8,9,10,11for (int i = 0; i < borrowMonth; i++) {//算2月份的最大天数//用Calendar计算Calendar calendar = Calendar.getInstance();calendar.set(y, m+i+1, 1);//天数-1calendar.add(Calendar.DAY_OF_MONTH, -1);//错误的使用了set方法,导致天数没有31天的//取出日期中年月日int hy = calendar.get(Calendar.YEAR);int hm = calendar.get(Calendar.MONTH)+1;int hd = calendar.get(Calendar.DAY_OF_MONTH);//当月的最大天数//还款日默认情况下就是借款日int huanMoney = d;//借款日大于当月的最大天数if (d > hd) {huanMoney = hd;}String str2 = hy+ "-" + hm + "-" + huanMoney; list.add(str2);}return list;}
}
- 等额本息:每个月还的本金一样,利息递减
public class Repayment {//当月本金private double principal;//还款期数private int index;//当月利息private double interest;//还款日期private String date;public Repayment() {super();// TODO Auto-generated constructor stub}public Repayment(double principal, int index, double interest, String date) {super();this.principal = principal;this.index = index;this.interest = interest;this.date = date;}public double getPrincipal() {return principal;}public void setPrincipal(double principal) {this.principal = principal;}public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}public double getInterest() {return interest;}public void setInterest(double interest) {this.interest = interest;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}@Overridepublic String toString() {return "Repayment [当月本金=" + principal + ", 还款期数=" + index + ", 当月利息=" + interest + ", 还款日期=" + date+ "]";}}
public class Demo01 {public static void main(String[] args) {//等额本息计算(按月还款-按月算)/*等额本息(每月等额)还款计算:1.等额本息每个月的还的本金一样,利息递减2.公式:本金/12 + 剩余本金 * 月利息(1%)*/System.out.println("还款方式:等额本息");List<Repayment> list = new ArrayList<Repayment>();//1.借款金额double borrowMoney = 10000;System.out.println("借了:"+borrowMoney);//2.还款的期数int index = 21;System.out.println("借款期数:"+index);//3.计算每个月还款的本金double principal = borrowMoney / index;//System.out.println(principal);//小数点太多了principal = Double.parseDouble(String.format("%.2f", principal));//设置保留两位小数点//借款日期Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String s= sdf.format(date);//借款月利率(1分2)double rate = 0.012;System.out.println("月利率:"+rate);System.out.println("借款日期:"+ s);//小数点保留2位//4.计算未来12个月还款数据for (int i = 0; i < index; i++) {//4.1计算好还款日期//调用了我封装的方法List<String> list2 = FinanceUtil.replyDateList(date, index);String hdate = list2.get(i);//还款日期//4.2设置还款期数int hqishu = i+1;//4.3设置当月的本金double dbenjin;if (i < index - 1) {dbenjin = principal;//0-11期的应还本金}else {//最后一期本金dbenjin = borrowMoney - (index - 1)*principal;dbenjin = Double.parseDouble(String.format("%.2f", dbenjin));}//4.4设置利息/*** 公式:利息:剩余本金 * 月利息(0.012)*/double lixi = (borrowMoney - dbenjin*i)*rate;lixi = Double.parseDouble(String.format("%.2f", lixi));//把属性封装到对象Repayment repayment = new Repayment(dbenjin,hqishu, lixi, hdate);//把对象存到集合list.add(repayment);}//5.遍历for(Repayment re : list){System.out.println(re);}}
}
- 先息后本:前面n个的只还利息,最后一个,利息+所有本金
public class Demo02 {public static void main(String[] args) {/*先息后本款计算:前11个月 本金*月利息(1%)最后一个月 本金 + 本金*月利息(1%)
*/System.out.println("还款方式:先息后本");List<Repayment> list = new ArrayList<Repayment>();//1.借款金额double borrowMoney = 10000;System.out.println("借了:"+borrowMoney);//2.还款的期数int index = 12;System.out.println("借款期数:"+index);//3.计算每个月还款的本金double principal = 0;principal = Double.parseDouble(String.format("%.2f", principal));//设置保留两位小数点//借款日期Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String s= sdf.format(date);//借款月利率(1分2)double rate = 0.012;System.out.println("月利率:"+rate);System.out.println("借款日期:"+ s);//小数点保留2位//4.计算未来12个月还款数据for (int i = 0; i < 12; i++) {//4.1计算好还款日期//调用了我封装的方法List<String> list2 = FinanceUtil.replyDateList(date, index);String hdate = list2.get(i);//还款日期//4.2设置还款期数int hqishu = i+1;//4.3设置当月的本金double dbenjin;if (i < index - 1) {dbenjin = principal;//0-11期的应还本金}else {//最后一期本金dbenjin = borrowMoney;dbenjin = Double.parseDouble(String.format("%.2f", dbenjin));}//4.4设置利息/*** 公式:利息:剩余本金 * 月利息(0.012)*/double lixi = borrowMoney*rate;lixi = Double.parseDouble(String.format("%.2f", lixi));//把属性封装到对象Repayment repayment = new Repayment(dbenjin,hqishu, lixi, hdate);//把对象存到集合list.add(repayment);}//5.遍历for(Repayment re : list){System.out.println(re);}}
}
面试题
1.HashMap和Hashtable区别
- Hashtable是JDK1.0版本出现的,是线程安全的,效率低,有加锁(看原码)[很少用]
- HashMap是JDK1.2版本出现的,是线程不安全的,效率高
- Hashtable不可以存储null键和null值
- HashMap可以存储null键和null值
public static void main(String[] args) {//hashMap对象HashMap<String,String> map = new HashMap<String,String>();map.put("name", "gyf");map.put(null, null);System.out.println(map);//Hashtable对象Hashtable<String,String> table = new Hashtable<String,String>();table.put("name", "gyf");table.put(null, null);//Hashtable不可以存储null键和null值System.out.println(table);}
总结
通过对Set、Map的学习,对集合有了更深入的认识,对排序有了更深的印象,在斗地主案例里面,灵活的运用了Map的键值对特性,存扑克牌,然后用TreeSet集合存序号,这样得到的手牌就会自动排序,得到序号后再用ArrayList集合存序号所对应的牌,然后对比数组中的Arrays工具类,集合也有自己的工具类Collectiongs.练习了金融利息算法(包括等额本息、先息后本两种还款方式),遇到了保留小数点的问题,查阅,可以用String的format("%.2f",需要保留小数点的数)转化。自己封装了这两个方法,作为工具类。以后算利息,一行代码就可以搞定!
学Java第十三天(至Map)相关推荐
- 教妹学Java(二十三):怎么理解 Java 中对象和类的概念?
你好呀,我是沉默王二,CSDN 排名前十的博客专家.这是<教妹学 Java>专栏的第二十三篇,我们来理解一下 Java 中的对象和类,以及它们俩的概念--什么是对象?什么又是类? 本专栏中 ...
- 教妹学Java(三十三):super 关键字的用法
你好呀,我是沉默王二,(目前是)CSDN 周排名前十的博客专家.这是<教妹学 Java>专栏的第二十七篇,今天我们来谈谈 Java 的 super 关键字--super 关键字有哪些用法? ...
- 学JAVA第十三天,方法、方法重载及构造函数
今天终于不讲狗跳楼的问题了,今天讲了方法,方法重载及构造函数及构造函数重载的课程了. 这里说了有参好无参的,下面讲构造函数重载和方法重载. 其实,这上面写的这些方法,就相当一个模板.想要快速做出产品就 ...
- 【零基础学Java】—网络编程(五十三)
[零基础学Java]-网络编程(五十三) 一.软件结构 C/S结构:全称为Client/Server结构,是指客户端和服务器结构,常见的程序有QQ.迅雷等软件 B/S:全称为Browser/Serve ...
- 【零基础学Java】—对象数组(十三)
[零基础学Java]-对象数组(十三) /*** @author :CaiCai* @date : 2022/4/7 11:08*/ public class demo05 {public stati ...
- 教妹学Java(十三):if-else 语句详解
大家好,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员.本篇文章通过我和三妹对话的形式来谈一谈"if-else 语句". 教妹学 Java,没见过这么有趣的标题吧?& ...
- 二十三、JAVA中的Set和Map
JAVA中的Set和Map 1. Set接口 1.1 概述 1.2 特点 1.3 常用方法 1.4 案例 测试常用方法 2. HashSet 2.1 概述 2.2 案例 获取HashSet里的元素 3 ...
- 跟我学 Java 8 新特性之 Stream 流(六)收集
转载自 跟我学 Java 8 新特性之 Stream 流(六)收集 我们前面的五篇文章基本都是在说将一个集合转成一个流,然后对流进行操作,其实这种操作是最多的,但有时候我们也是需要从流中收集起一些 ...
- 跟我学 Java 8 新特性之 Stream 流(二)关键知识点
转载自 跟我学 Java 8 新特性之 Stream 流(二)关键知识点 我们的第一篇文章,主要是通过一个Demo,让大家体验了一下使用流API的那种酣畅淋漓的感觉.如果你没有实践,我还是再次呼吁 ...
最新文章
- python str转dict_在python中将str转换为dict
- 用ABAP实现SM36的设置后台JOB
- python序列_什么是Python的序列协议?
- 五十、Maven系列:安装和配置Maven镜像
- RHEL6.2上使用 libvirt创建和管理KVM虚拟机
- 程序员的世界有 10 种人,你是哪一种?
- ORA-12514: TNS:listener does not currently know of service …
- mapreduce对日志数据上下行流量汇总
- c语言pwm调制方式,pwm如何进行调制?3种pwm调制方式介绍
- python基础:os模块
- 解决Android logcat: Unexpected EOF!方法指南
- 【嵌入式开发】开发板设置系统时间
- CSAPP LAB4 键盘驱动程序的分析与修改(谢罪)
- 网盾极风云:五分钟搞懂HTTP和HTTPS
- 如何在程序里写死一张图片(base64编码,OpenCV)
- UNIT07 BREs EREs PREs
- Spring IOC IOP
- 单招报计算机要考什么,单招考试一般都考什么内容
- VVC参考软件的下载安装
- 文件 md5去重 linux,对比文件md5值实现去重文件
热门文章
- 30、T5L 迪文屏 C51开发之 ADC模数转换
- Codeforces 1633 E. Spanning Tree Queries ——暴力,kruskal,思维
- 对越Altium Designer 17.0.9电路设计软件
- JavaScript 推断浏览器类型及32位64位
- 互联网企业使用云计算,有什么优势?
- am335x linux内核烧写_am335x文件系统烧写问题
- HTML特殊字符编码对照表 —— (二)
- Swift新async/await并发模型中子任务取消不能被其它子任务感知的原因及解决
- 阿里云DTS订阅实现实时运营服务的方案及注意事项
- vim使用自定义snippets