1、泛型的基本概念html
泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type)的应用,也就是说所操做的数据类型被指定为一个参数,在用到的时候在指定具体的类型。这种参数类型能够用在类、接口和方法的建立中,分别称为泛型类、泛型接口和泛型方法。java
package other; public class Test { private Object a; // 定义Object类型成员变量 public Object getA() { // 设置get方法 return a; } public void setA(Object a) { // 设置set方法 this.a = a; } public static void main(String[] args) { Test t = new Test(); t.setA(new Float(12.3)); Integer f = (Integer)(t.getA()); System.out.println(f); } }
由于不存在语法错误,因此编译器不会报错,可是在运行的时候会出现ClassCastException的异常。由此看来,“向下转型”操做一般会出现问题,而泛型机制能够很好的解决这个问题。程序员
MutiOverClass<T1,T2> //MutiOverClass为泛型类名称
2.泛型接口的定义
泛型接口和泛型类的定义方法相似,语法以下:算法
interface MutiOverInte<T1,T2>
3.泛型方法的定义
泛型方法的定义就比较复杂,其语法以下:
图片引用自这安全
4、类型通配符ide
在泛型机制中,提供了类型通配符,其主要做用是在建立一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。要声明这样一个对象可使用“?”通配符来表示,同时使用extends关键字来对泛型加以限制。函数
其语法以下:工具
泛型类名称<? extends List> a = null //<? extends List>表示类型未知,当须要使用该泛型对象时,能够单独实例化
另外,泛型类不止能够向下限制,还能够进行向上限制,这就要用到super
关键字便可,如泛型类名称<? super List> a = null
学习
//菱形语法 List<String> strList = new ArrayList<String>(); //java7之前 List<String> strList = new ArrayList<>(); //java7时
//java的foreach语句 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7); numbers.stream().filter(i -> i % 2 == 0)..forEach(System.out::println);
//使用Map.Entry对元素进行遍历,并使用匿名内部类实现对map中元素的排序 List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { if (o1.getValue() == o2.getValue()) { return o1.getKey().compareTo(o2.getKey()); } return o2.getValue() - o1.getValue(); } });
本次做业题集集合
测试
答:这题比较容易,就是一开始遍历List的时候,没有考虑到从0开始遍历删除元素时后面元素下标的变化,致使有些本该删除的元素没有被删除。
在List中删除元素的方法:
//删除list中的偶数元素 List<Integer> list = new ArrayList<Integer>(); for(int i=0;i<10;i++){ //往list中添加元素 list.add(i); }
//方法一:从前日后遍历删除元素 for(int i=0;i<list.size();i++){ if(list.get(i)%2==0){ list.remove(i); i--; } }
//方法二:反向遍历删除元素 for(int i=list.size()-1;i>=0;i--){ if(list.get(i)%2==0) list.remove(i); }
//方法三:利用Iterator删除元素 for(Iterator<Integer> iterator = list.iterator();iterator.hasNext(); ){ int e = iterator.next(); if(e%2==0) iterator.remove(); }
//方法四:新建一个新集合来删除元素 List<Integer> newList = new ArrayList<Integer>(); for(Integer e:list){ if(e%2==0) newList.add(e); } list.removeAll(newList);
//方法五:利用removeIf删除某一个元素 list.removeIf(e -> e%2==0);
//输出删除完成后列表(以上五个运行结果都同样,就贴一张图了) System.out.println(list);
运行结果:
//方法六:利用forEach()过滤元素 list.stream().filter(e ->e%2==1).forEach(System.out::println);
运行结果:
诶,上次的做业中彷佛写过了,那就照搬过来吧
建立HashMap对象map 循环读入文章中的单词 IF 读入单词为”!!!!!” 退出循环 ELSE IF map中没有相应的key 添加单词到map中并设置value为1 ELSE 将key对应的value值加1 建立ArrayList对象list 实现Collections接口对map对象进行排序 输出map的长度 输出排序后list中前十个数据
答:这题中用到了HashMap,key值为单词,value值为单词出现的次数,这题比较复杂的地方就是要使用一个可以存放Map数据ArrayList来实现Collections接口来实现相应的排序。
关键代码以下:
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { if (o1.getValue() == o2.getValue()) { return o1.getKey().compareTo(o2.getKey()); } return o2.getValue() - o1.getValue(); } });
其中Map.Entry为Map的一个内部接口,它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。使用它能够更方便咱们去访问Map中的元素。
本题较难,作不出来没关系。但必定要有本身的思考过程,要有提交结果。
建立Map对象map,其中key类型为String,value类型为ArrayList 建立ArrayList对象line 循环读入文章中的单词 IF 读入单词为"!!!!!" 退出循环 ELSE IF map中没有相应的key 添加单词到map中并将当前行数的值添加到value中 ELSE 判断当前行数是否已经存在于value中,若没有,则添加当前行数到value中 建立迭代器Iterator 遍历输出map中的内容 输入一行字符串以空格分开 IF map中不一样时存在指定单词 输出found 0 results ELSE 求指定单词的value值的交集 IF 交集为0 输出found 0 results ELSE 输出交集以及交集中数字对应的行数
答:这题比较好玩的地方就是要在要将Map的value的类型设置为ArrayList的,以方便存储单词出现行数,而后要注意的点就是将某一单词的当前行数加入ArrayList中时要判断列表中是否已经存在该行的行数,即这个单词是否在这行中出现屡次,以前一直错误就是由于没有考虑到一行能够存放多个相同单词,而后使用Iterator迭代器进行Map的输出。最后求单词出现函数的实质其实就是求指定单词的出现行数的交集,能够用retainAll方法来求。
编写一个Student类,属性为:
private Long id; private String name; private int age; private Gender gender;//枚举类型 private boolean joinsACM; //是否参加过ACM比赛
建立一集合对象,如List
List<Student> search(Long id, String name, int age, Gender gender, boolean joinsACM)
,而后调用该方法将id>某个值,name为某个值, age>某个值, gender为某个值,参加过ACM比赛的学生筛选出来,放入新的集合。在main中调用,而后输出结果。(截图:出现学号、姓名)测试数据:
List<Student1> student = new ArrayList<Student1>(); student.add(new Student1(1L,"wang",15,Gender.man,false)); student.add( new Student1(8L,"zhao",16,Gender.woman,true)); student.add( new Student1(87L,"chen",17,Gender.man,false)); student.add ( new Student1(100L,"xu",18,Gender.woman,false)); student.add( new Student1(67L,"chen",19,Gender.man,true)); student.add( new Student1(90L,"chen",20,Gender.man,true)); student.add( new Student1(177L,"chen",21,Gender.man,true));
//搜索方法 static List<Student1> search(Long id, String name, int age, Gender gender, boolean joinsACM,List<Student1> list){ List<Student1> student = new ArrayList<Student1>(); for(Student1 e:list){ if(e.getId()>id&&e.getName().equals(name)&&e.getGender()==gender&&e.isJoinsACM()==joinsACM){ student.add(e); } } return student; }
//main函数 List<Student1> newStudent = search(50L, "chen",18,Gender.man, true,student); for(Student1 e:newStudent){ System.out.println(e.toString()); } }
运行截图:
List<Student1> newStudent = student.stream().filter(e -> e!=null&&e.getId()>50&&e.getName().equals("chen")&&e.getAge()>18&&e.getGender()==Gender.man&&e.isJoinsACM()==true).collect(Collectors.toList());
测试数据(只是添加了两个null进去):
student.add(new Student1(1L,"wang",15,Gender.man,false)); student.add( new Student1(8L,"zhao",16,Gender.woman,true)); student.add(null); student.add( new Student1(87L,"chen",17,Gender.man,false)); student.add(null); student.add ( new Student1(100L,"xu",18,Gender.woman,false)); student.add( new Student1(67L,"chen",19,Gender.man,true)); student.add( new Student1(90L,"chen",20,Gender.man,true)); student.add( new Student1(177L,"chen",21,Gender.man,true));
运行结果:
其实和上面的结果是同样的……
题集jmu-Java-05-集合
之GeneralStack
interface GeneralStack<T>{ T push(T item); T pop(); T peek(); public boolean empty(); public int size(); }
ArrayListIntegerStack
相比,说明泛型有什么好处答:在ArrayListIntegerStack中
,栈中的元素只能是Integer类型的,内容比较有局限性,而使用了泛型,则能够根据本身的要求来规定入栈元素的类型,就像这题中,咱们只要定义一个接口就能够实现对Integer
、Double
和Car
类型的栈操做,减小了代码的冗余,使用起来也很灵活。
基础参考文件GenericMain,在此文件上进行修改。
String max = max(strList)
能够运行成功,其中strList为List<String>
类型。也能使得Integer maxInt = max(intList);
运行成功,其中intList为List<Integer>
类型。注意:不得直接调用Collections.max函数。//max方法 public static <T extends Comparable<T>> T max(List<T> list){ Collections.sort(list); return list.get(list.size()-1); }
测试数据:
List<String> listA = new ArrayList<String>(); listA.add("aaaaa"); listA.add("bbbbb"); listA.add("ddddd"); listA.add("ccccc"); System.out.println(max(listA));
运行结果:
测试数据:
List<Integer> listB = new ArrayList<Integer>(); listB.add(11111); listB.add(22222); listB.add(44444); listB.add(33333); System.out.println(max(listB));
运行结果:
//max1方法 public static <T extends Comparable< ? super T>> T max1(List<T> list,Comparator< ? super T> comp) { Collections.sort(list,comp); return list.get(list.size()-1); }
测试数据:
List<StuUser> listC = new ArrayList<StuUser>(); listC.add(new StuUser(11, "aaa")); listC.add(new StuUser(22, "bbb")); listC.add(new StuUser(44, "ccc")); listC.add(new StuUser(33, "eee")); listC.add(new StuUser(33, "ddd")); User user1 = max1(listC,new StuUserComparator()); Object user2 = max1(listC,new StuUserComparator()); System.out.println(user1); System.out.println(user2);
运行结果:
int myCompare(T o1, T o2, Comparator c)
方法,该方法能够比较两个User对象,也能够比较两个StuUser对象,传入的比较器c
既能够是Comparator<User>
,也能够是Comparator<StuUser>
。注意:该方法声明未写全,请自行补全。//myCompare方法 public static <T> int myCompare(T o1,T o2, Comparator<? super T> c){ return c.compare(o1, o2); }
测试数据:
User user1 = new User(123); User user2 = new User(321); int a = myCompare(user1,user2,new UserReverseComparator()); if(a<0) System.out.println(user1+" > "+user2); else if(a==0) System.out.println(user1+" = "+user2); else System.out.println(user1+" < "+user2);
StuUser stu1 = new StuUser(44, "ccc"); StuUser stu2 = new StuUser(55, "ddd"); int b = myCompare(stu1,stu2,new StuUserComparator()); if(a<0) System.out.println(stu1+" > "+stu2); else if(a==0) System.out.println(stu1+" = "+stu2); else System.out.println(stu1+" < "+stu2);
运行结果:
集合实验文件中的第07次实验(集合).doc文件,里面的题目6.
建立HashSet对象dic Add word to dic 设置最大截取长度maxLength While has nextLine{ Creat list While line 的长度不为0{ 从后往前以最大截取长度截取句子e If dic.continue(e){ Add e to list line = 截取字符串(0,line.size-e.size) 从后往前以最大截取长度截取句子e } Else 去掉e的第一个字符继续操做 } 倒序输出list中的元素 }
题目集:jmu-Java-05-集合
在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 而后搜索并截图
须要有两张图(1. 排名图。2.PTA提交列表图)
须要将每周的代码统计状况融合到一张表中。
本身的目标能实现吗?
恩第一周定的目标是到期末可以写7000+行的代码,看样子应该能够完成??
周次 | 总代码量 | 新增代码量 | 总文件数 | 新增文件数 |
---|---|---|---|---|
2 | 607 | 607 | 15 | 15 |
3 | 1642 | 1035 | 33 | 18 |
5 | 2044 | 402 | 42 | 9 |
6 | 2874 | 830 | 57 | 15 |
7 | 3161 | 287 | 63 | 6 |
8 | 4299 | 1138 | 72 | 9 |
9 | 4831 | 532 | 81 | 9 |
10 | 5475 | 644 | 93 | 12 |
尝试从如下几个维度评估本身对Java的理解程度
维度 | 程度 |
---|---|
语法 | pta的题目基本上没问题吧,一些比较偏的语法也能够经过百度解决 |
面向对象设计能力 | 这方面的能力还比较弱,在设计购物车系统的时候充分暴露了出来,正在努力改善中 |
应用能力 | 也许借助一些资料能够完成一些简单的工具? |
至今为止代码行数 | 5475 |