文章目录
2022.1.15
其他
-
public class PokeDemo { public static void main(String[] args ){ try { Pokemon a1 = PokemonManage.getPokemon("Surf"); a1.eat(); a1.skill(); }catch (Exception e){ e.printStackTrace(); } } }
-
注意下,这种写法下会导致a1在{}作用域外无法使用
-
所以针对异常处理的话,我个人感觉他不是用来在主函数里进行对象创建的时候用的,而是检验算法中正确性用的
-
论正确的如何在创建对象的过程中完成对错误的鉴定
Pokemon pokemon = null; try{ if(a.equals("Surf")){ pokemon= new Pachirisu(); }else if(a.equals("Cut")){ pokemon= new Lapras(); }else if (a.equals("Cut Surf")){ pokemon= new Furret(); }else if(a.equals("Cut,Surf")){ pokemon = new Furret(); }else { throw new Exception("Please input again , because your operation is out of order"); } return pokemon; }catch (Exception e){ e.printStackTrace(); return null; } }
-
-
如何在格式字符串输出的时候里面包含双引号,可以按下面的操作
throw new Exception("Please input again and make sure that your operation is in the range of " + "\"Cut\" and \"Surf\" and \"Cut Surf\"");
-
请说说 Java 中抽象类和接口的不同之处
- 我自己通过查资料,早期的接口其实没有default这种方法,也就是说,它全部都是抽象方法,每一个都需要实现对象去实现,而抽象类不是,抽象类可以自己先定义一些方法,然后选择让子类去实现那些抽象方法,并重写父类中定义的方法,只要符合规范就好,当然,自从接口有了default的方法以后,这个差别就没有了感觉
- 然后就是抽象类和子类是单继承的关系,也就是说子类只能有一个父类,但是接口不一样,一个类可以实现多个接口.
- 抽象类中可以定义私有方法,但是接口不行
-
接口的变量默认被什么修饰符修饰? 方法呢?
-
接口的变量默认被修饰为public static final类型,方法默认被public修饰符修饰
public class two implements three { enum test{ a,b,c,d,e,max } //three.a=89; @Override public void test() { System.out.println("hello "); } public static void main(String[] args){ //three.a=99; System.out.println(three.a); } }
-
-
接口中只能有 public 公有方法 这句话正确咩?
- 我其实有点不太理解这句话,因为接口里还可以有属性(狗头)
- 如果说的是能不能有private修饰的方法的话,我的答案是不能,因为接口设计出来就是让类实现方法用的,如果执着定义私有方法,不如直接用抽象类来的舒服
-
父类如果实现了一个接口的话,子类就会默认继承父类实现的接口,即便接口里被父类实现的方法存在默认方法
public interface three { int a=9999; void test(); public default void testTwo(){ System.out.println("this is a test"); } }
public class two implements three { enum test{ a,b,c,d,e,max } //three.a=89; @Override public void test() { System.out.println("hello "); } public static void main(String[] args){ //three.a=99; System.out.println(three.a); three Three = new two(); } }
public class four extends two{ public static void main(String[] args){ four test = new four(); test.test(); } }
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)
-
2022.1.20
问题
集合
Map
-
如何通过key来进行查找
Set<String> keySet= map.keySet(); String a = input.next(); for(String key : keySet){ if(key.equals(a)){ System.out.println("find it and the key is "+key+" the value is " + map.get(key)); } }
-
如果插入的key值是有重复的,那么以后面的为准,前面的key值会被刷新
其他
2022.1.21
问题
集合
Map
-
如何先HashMap中添加入我们自定义的类
while(i<3){ String id = input.next(); if(GoodMap.containsKey(id)){ continue; } String name = input.next(); double value = input.nextDouble(); Goods good = new Goods(id,name,value); GoodMap.put(id,good); i++; }
2022.1.23
思考题
-
List list = new ArrayList(); 能添加各种类型的数据吗?
-
理论上可以添加数据,就像下面这样
package thinkingOne; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class testOne { public static void main(String[] args) { List list = new ArrayList(); list.add(new Integer((3332432))); list.add("afhfhad"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).toString()); } } }
-
不过有时也会出现运行时错误,比如下面这种
public class testOne { public static void main(String[] args) { List list = new ArrayList(); list.add(new Integer(3141)); list.add("afhfhad"); for (int i = 0; i < list.size(); i++) { String str =(String) list.get(i); System.out.println(str); } } }
-
所以需要泛型来对list中的变量进行约束
-
如果容器中的数据类型不确定,那么在使用前,应该先进行类型判断再使用,从而避免运行时异常。
if (list.get(i) instanceof String){ String str = (String) list.get(i); }
-
-
List list = new Array()会报错吗?为什么?
-
会报错
public class testOne { public static void main(String[] args) { List<Object> list =new Array<Integer>(); list.add(1); } }
-
因为List和Array间,前者表示列表,后者表示数组,二者其实不同
-
如果改成
public class testOne { public static void main(String[] args){ List<Object> list = new ArrayList<Integer>(); } }
好像也一样报错,就两种不会报错
List<Object> list = new ArrayList<>(); List<Object> list = new ArrayList();
不过添加Integer的元素时,会显示无法向Object转型
-
-
什么时候用?、extends、super?
-
我没看太懂这个问题,我对这个的理解就是什么时候用extend和super,所以下面写一下
-
用exetend就是写我想写一个类,并且这个类和某一个类具有明显的继承关系时,我就会用extend,以此表示这个类是某个类的子类,以减少一些代码量
-
用super(),我用这个就常用的就是访问父类的构造方法,当然它还可以用来访问父类的一些变量,和一些方法,下面用代码展示下
package thinkingOne; public class testOne { public static void main(String[] args){ dog1 testOne = new dog1(1,2); testOne.fun2(); } } class dog{ private int a,b; public dog(int a,int b) { this.a = a; this.b = b; } String name = "I am the one"; void fun1(){ System.out.println("hello"); } } class dog1 extends dog{ public dog1(int a,int b){ super(a,b); } public void fun1(){ System.out.println(name); } public void fun2(){ super.fun1(); fun1(); } }
-
然后再写上面的时候发现了我几个问题吧
-
private修饰符不能通过super.变量名进行访问,protected可以
-
然后不能直接在class里写super.父类方法名,比如这样
super.fun1();
要这么写
public void fun2() { super.fun1(); }
其中修饰符你随意就好
-
-
-
List<?>和List的区别?
- List<?>,即通配符类型,其引用变量,同样可以接受任何对应List的参数化类型,包括List,但不能添加任何元素,保证了安全性和表述性。但不具有表述性,从中取出的元素时Object类型,要通过手动转换才能得到原本的类型。
- List,即实际类型参数为Object的参数化类型,其引用变量可以接受List,可以添加元素,但不能接受除了其本身外的任何参数化类型(泛型的子类型化原则)
查阅时一些有趣的信息
- 泛型信息可以在运行时被擦除,泛型在编译期有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉。归根结底不管泛型被参数具体化成什么类型,其class都是RawType.class,比如List.class,而不是List.class或List.class
其他
ed可以
3. 然后不能直接在class里写super.父类方法名,比如这样
```java
super.fun1();
```
要这么写
```java
public void fun2() {
super.fun1();
}
```
其中修饰符你随意就好
-
List<?>和List的区别?
- List<?>,即通配符类型,其引用变量,同样可以接受任何对应List的参数化类型,包括List,但不能添加任何元素,保证了安全性和表述性。但不具有表述性,从中取出的元素时Object类型,要通过手动转换才能得到原本的类型。
- List,即实际类型参数为Object的参数化类型,其引用变量可以接受List,可以添加元素,但不能接受除了其本身外的任何参数化类型(泛型的子类型化原则)
查阅时一些有趣的信息
- 泛型信息可以在运行时被擦除,泛型在编译期有效,在运行期被删除,也就是说所有泛型参数类型在编译后都会被清除掉。归根结底不管泛型被参数具体化成什么类型,其class都是RawType.class,比如List.class,而不是List.class或List.class