java学习笔记2022.1.16
问题
-
HashSet<Cat> set = new HashSet<Cat>(); for(Cat cat : set){ if(cat.getName().equals("fanfa")){ set.remove(cat); } }
什么情况下上述代码存在问题?set里存在元素
- 如果要是该语句正确,需要在找到以后直接break,否则报错,这个主要因为集合在设计时为了保证数据的互异性对数据的读取进行了限制(更深层的源码实现我还没看,所以更具体的东西我也不懂)
集合
-
链表.get(i)方法得到的是一个链表元素,相当于从属于链表这个父类,所以如果我们需要调用链表元素中的特有方法的话,必须对链表元素进行强制类型转化如下
for (int i = 0; i < noticeList.size(); i++){ System.out.println(i+1+":"+((Notice)(noticeList.get(i))).getTitle()); }
-
然后注意下,可以通过i+1加上字符串的形式写出类似于自动填写序号的作用
-
注意下noticeList.size()不要忘了后面的括號
-
public class NoticeTest { public static void main(String[] args) { Notice notice1 = new Notice(1, "own", "one", new Date()); Notice notice2 = new Notice(2, "own", "two", new Date()); Notice notice3 = new Notice(3, "own", "three", new Date()); ArrayList noticeList = new ArrayList(); noticeList.add(notice1); noticeList.add(notice2); noticeList.add(notice3); System.out.println("the content of Notice :"); for (int i = 0; i < noticeList.size(); i++){ System.out.println(i+1+":"+((Notice)(noticeList.get(i))).getTitle()); } System.out.println("--------------------------------------------"); Notice notice4 = new Notice(4, "own", "four",new Date()); noticeList.add(1,notice4); System.out.println("the content of Notice :"); for (int i = 0; i < noticeList.size(); i++){ System.out.println(i+1+":"+((Notice)(noticeList.get(i))).getTitle()); } System.out.println("-------------------------------------------"); noticeList.remove(2); System.out.println("the content of Notice :"); for (int i = 0; i < noticeList.size(); i++){ System.out.println(i+1+":"+((Notice)(noticeList.get(i))).getTitle()); } System.out.println("----------------------------------------------"); notice4.setTitle("hello"); noticeList.set(1,notice4); for(int i=0;i<noticeList.size();i++){ System.out.println(i+1+":"+((Notice)(noticeList.get(i))).getTitle()); } } }
注意下set方法的使用,并不是直接修改,而是通过修改元素然后修改的链表
-
-
Set
-
有关于如何向集合中添加元素并且输出
package Eetjihe; import java.util.HashSet; import java.util.Iterator; public class one { public static void main(String[] args) { HashSet set = new HashSet(); set.add("red"); set.add("green"); set.add("yellow"); set.add("blue"); Iterator it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()+" "); } } }
-
注意,Set类的实例没有直接可以调用元素的方法,所以需要利用迭代器进行操作
-
注意迭代器操作的时候不要写成这个样子
while (it.hasNext()) { System.out.println(it+" "); }
这是一个死循环,因为it不能自己到下一个元素,并且此时输出来的应该是it的地址
-
-
向集合中插入元素,编译器是不会报错的,且集合内不会出现重复元素
-
如何将自定义类加入到hashset中去
package Eetjihe; public class Cat { private String name; private int month; private String species; public Cat(String name, int month, String species){ this.month=month; this.species=species; this.name=name; } public int getMonth() { return month; } public String getSpecies() { return species; } public String getName() { return name; } public void setMonth(int month) { this.month = month; } public void setName(String name) { this.name = name; } public void setSpecies(String species) { this.species = species; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + ", month=" + month + ", species='" + species + '\'' + '}'; } }
package Eetjihe; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class catTest { public static void main(String[] args){ Cat huahua = new Cat("huahua",12,"English"); Cat fanfan = new Cat("fafan",1,"Chinese"); Set set = new HashSet(); set.add(huahua); set.add(fanfan); Iterator it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()+" "); } } }
还有注意下,输出语句还可以写成这样
for (int i=0;i<set.size();i++){ System.out.println(it.next()); }
-
为了防止set在添加自定义类时添加了重复数据,我们需要重设hashCode方法和equals方法,因为hashCode我直接按照系统默认来的,等数据结构解决了在回来处理这个问题,暂时先跳过,equals方法按照下面的来写
@Override public boolean equals(Object obj) { if(this==obj) { return true; } if(obj.getClass()== Cat.class){ Cat cat = (Cat) obj; return cat.getName().equals(this.name) && cat.getMonth()==(this.month) && cat.getSpecies().equals(this.species); } return false; }
-
在上面,obj首先是由对象向上转型得到的,然后getClass()方法得到的是class文件信息,每一个实例对象都归属于一个class文件信息,我只是粗略的了解下,这里包含二进制文件的一些内容,但也不是很深,我选择先跳过,因为当前我觉得还没必要理解那么深入就可以解决问题了
- 注意下类名.class也是一种获取class文件信息的方法
-
然后处理下第一个if的问题:这个理解起来其实挺简单的,就是直接比较地址,如果地址相同的话,那么二者必然相同,这没啥好说的
-
第二个if是先判断两者的class文件是否相同,如果相同就将obj进行强制转化成所需类型.然后进行上面的比较就好
-
然后为什么传入obj类型:因为任何类型都可以强制转化成Object类型,如果不用Object类型的话,用一个具体的类的话,如果我们用了个不同于这个具体类的对象的话,程序会不知道怎么处理,然后直接给你来个报错
-
-
如何通过变量名查找和通过类中变量查找
it=set.iterator(); if(set.contains(huahua)){ System.out.println(huahua); }else{ System.out.println("没有信息"); } boolean flag=false; while(it.hasNext()){ Cat cat = (Cat) it.next(); if(cat.getName().equals("huahua")){ flag=true; } } if(flag){ System.out.println("find it"); }else{ System.out.println("No"); }
- 注意下Iterator 的实例对象每一次都要重新赋值,因为每一次遍历完成以后,其实例对象应该都在最后了,不会自动返回和自动更新
-
泛型的使用
-
Set<Cat> set = new HashSet<Cat>(); Iterator<Cat> it = set.iterator();
-
上面的写法保证了自动转化时都是我们需要的类型,不需要进行强制类型转化
-
-
如何删除集合中的元素
-
删除单个元素
for (Cat cat : set){ if(cat.getName().equals("huahua")){ set.remove(cat); break; } }
-
删除多个元素
HashSet<Cat> set1= new HashSet<Cat>(); for (Cat cat : set){ if(cat.getMonth()<=10){ set1.add(cat); } } set.removeAll(set1);
-
Map
-
创建HashMap
HashMap<String,String> map = new HashMap<String,String>();
-
添加HashMap数据
Scanner input = new Scanner(System.in); HashMap<String,String> map = new HashMap<String,String>(); for(int cnt=0;cnt<3;cnt++) { String key = input.next(); String value = input.next(); map.put(key,value); }
-
用迭代器输出key和value
Iterator<String> it = map.values().iterator(); System.out.println("value is "); while(it.hasNext()) { System.out.println(it.next()); } it= map.keySet().iterator(); System.out.println("key is "); while(it.hasNext()) { System.out.println(it.next()); } Set<Map.Entry<String,String>> entrySet=map.entrySet(); System.out.println("key-value"); for(Map.Entry<String,String> entry : entrySet){ System.out.println(entry.getKey()+"-"+entry.getValue()); }
其他
-
如果你数据没有输完然后用了ctrl+D,会强制终止程序继续运行,并且还会给你报错,我得到的报错信息是下面这样的
Exception in thread "main" java.util.NoSuchElementException at java.base/java.util.Scanner.throwFor(Scanner.java:937) at java.base/java.util.Scanner.next(Scanner.java:1478) at zidian.one.main(one.java:12)
-