泛型
来源:互联网 发布:php就业方向 编辑:程序博客网 时间:2024/05/17 20:31
#泛型定义类型
* 运用泛型最大好处是可以避免类型转型异常,泛型就是引用数据类型,在泛型中不能用基础数据类型如"int",只能用其类型的包如"Integer"
* 指定多个泛型class Person<T,V>
* 在声明时指定泛型类型,如果没指定就会编译时出现警告,但仍然可以执行,因为没指定类型就默认是Object类型
```java
public static void main(String[] args){
//Person<String,int> p1 = new Person<String,int>("小李",5); error,不能用基础类型
Person<String,Integer> p1 = new Person<String,Integer>("小李",5);
System.out.println(p1.getName()+","+p1.getAge());
}
}
class Person<T,V>{ //多个泛型
private T name;
private V age;
public Person(T name, V age) {
this.name = name;
this.age = age;
}
public Person(){
}
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
public V getAge() {
return age;
}
public void setAge(V age) {
this.age = age;
}
}
```
#泛型通配符
* "?"(一般用于传参)
* 当你不确定泛型类型时就可以用"?",extends代表只能是子类和本身,super代表只能是父类和本身
```java
public class FloodType2 {
public static void main(String[] args) {
Person<String,Object> p = new Person<String,Object>("chen",2); //这里若将String换成Object就会出错,而将Integer换成Object就可以
new Person1().fun(p);
//Person<Object,Object> p = new Person<String,String>("chen",":"); error,泛型中不能用父类接收子类
}
}
class Person1{
public void fun(Person<? extends String,? super Integer> p){
System.out.println(p.getName()+" "+p.getAge());
}
}
```
#泛型接口
```java
public class FloodType3 {
public static void main(String[] args) {
AA<String> a = new AA<String>("chen");
BB b = new BB("ren");
System.out.println(a.fun1());
System.out.println(b.fun1());
}
}
//实现接口有两种方式
interface A<T>{
public T fun1();
}
class AA<T> implements A<T>{ //第一 种:在实例化对象时指明类型
public T fun1(){
return null;
}
}
class BB implements A<String>{ //第二种:在继承时指明类型
public String fun1(){
return null;
}
}
```
#泛型方法
```java
public class FloodType4 {
public static void main(String[] args) {
Test1 t = new Test1();
Test1 t2 = new Test1();
System.out.print(t.test("寝室号码:")); //传入String类型
System.out.print(t2.test(158)); //传入Integer类型
}
}
class Test1{
public<T> T test(T t){ //泛型广泛方法,在传参时确定类型,再返回此类型,注意:静态方法不能访问类上定义的泛型(静态随类加载而返回值还不确定,因此要报错)
return t;
}
}
```
#泛型数组
```java
public static void main(String[] args) {
Test1 t = new Test1();
Test1 t2 = new Test1();
Integer[] i = {1,4,5,2}; //注意:一定不能用int来定义数组,因为泛型不能使用基本数据类型
t.test1(i);
t2.test2(i);
}
class Test1{
public<T> void test1(T[] t){
for (int i=0; i<t.length; i++){
System.out.println(t[i]);
}
}
public<T> T[] test2(T[] t){
return t;
}
}
```
#泛型嵌套
```java
public class FloodType5 {
public static void main(String[] args) {
//使用了FloodType1中的Person类,此类有两个泛型
C<Person> c1 = new C<Person>(new Person<String,Integer>("chen",3)); //将Person类作为一种类型
C<Person<String,Integer>> cc = new C<Person<String,Integer>>(new Person<String,Integer>("jun",4)); //这种方式更为直观,与上面是一样代码却更为繁琐
}
}
class C<P>{
public C(){
}
public<T,V> C(Person<T,V> p) {
System.out.println(p.getName()+" "+p.getAge());
}
}
```
#集合
* 类集合就是一个动态的对象数组,一般很少直接使用Collection ,一般直接使用它的子接口,这样功能明确
#List
* List接口扩充了collection,所以拥有更多的方法,使用更方便,可以重复,实现子类ArrayList
```java
public class Collection1 {
public static void main(String[] args) {
List<Person> list1 = new ArrayList<Person>();
List<Person> list2 = new ArrayList<Person>();
Person p1 = new Person("chengdu",2);
//Person p2 = new Person("beijing",4);
Person p3 = new Person("shanghai",1);
Person p4 = new Person("tianjing",3);
System.out.println("添加对象");
list1.add(p1); //增加对象
list1.add(new Person("beijing",4));
System.out.println(list1);
System.out.println("在下标1处添加一组对象");
list2.add(p3);
list2.add(p4);
list1.addAll(1,list2); //在指定位置添加一组对象
System.out.println(list1);
System.out.println("移出第一个对象");
list1.remove(0); //移除对象
System.out.println(list1);
System.out.println("输出对象");
for (int i=0; i<list1.size(); i++){
System.out.println(list1.get(i)); //输出对象
}
System.out.println("将集合变为数组");
Object[] o = list1.toArray(); //将集合变为数组
for (Object a:o)
System.out.println(a);
System.out.println("用p2替换1位置上的对象");
list1.set(1, p4); //用指定对象替换指定位置对象
System.out.println(list1);
System.out.println("返回指定位置对象");
System.out.println(list1.get(1));
System.out.println("截取0到2的对象");
List<Person> list3 = list1.subList(0, 2); //截取指定位置的对象
System.out.println(list3);
System.out.println("查找'p2'的位置");
System.out.println(list1.indexOf(new Person("beijing",4))); //查找指定对象位置,当查找这个实例对象时,会自动调用重写的equals和hashCode方法来判断是否有相等的实例,这也是为什么字符串为什么可以直接查找到而对象不行,因为String类也重写了这两个方法
System.out.println("移除list1所有对象");
list1.clear(); //移除全部对象
System.out.println(list1);
System.out.println("判断list1是否为空");
System.out.println(list1.isEmpty()); //为空就返回true
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public String getName() {
return name;
}
public String toString() {
return this.name + this.age;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int hashCode() { //返回唯一的哈希码
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) { //判断两个实例是否相等
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) 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;
}
}
```
#LinkedList
* 链表操作符,继承了Deque所以具有队列的特点,先进先出
```java
public class Collection2 {
public static void main(String[] args) {
LinkedList<String> list1 = new LinkedList<String>(); //创建一个链表
list1.add("成都");
list1.add("上海");
list1.add("北京");
list1.add("天津");
System.out.println(list1);
list1.addFirst("云南"); //在头部添加对象
list1.addLast("桂阳"); //在后面添加对象
System.out.println(list1);
System.out.println(list1.element()); //查找头
System.out.println(list1.peek()); //查找头,这两种方式都很少用
System.out.println(list1.poll()); //查找头,然后删除,这种方式用的较多
System.out.println(list1);
int k = list1.size();
for (int i=0; i<k; i++){ //注意:不要直接用list1.size(),因为循环一次"poll"就会删除一个对象,长度会发生改变,会导致异常或是输出不完整
System.out.println(list1.poll());
}
}
}
```
#HashSet
* 采用散列存储(哈希算法就是计算散列存储位置的一种算法),所以是无序的,重复的只会出现一次(因为相同东西算出来的位置是一样的)
```java
public class Collection3 {
public static void main(String[] args) {
Set<String> s = new HashSet<String>();
s.add("成都");
s.add("上海");
s.add("天津");
s.add("广州");
System.out.println(s);
s.add("天津");
System.out.println(s); //如果是自己定义的类要求不能重复存储,则要重写equals和hashCode方法
}
}
```
#TreeSet
* 采用有序存放,它会将输入的对象按一定的算法顺序来存储
```java
public class Collection3 {
public static void main(String[] args) {
TreeSet<String> s1 = new TreeSet<String>();
s1.add("c");
s1.add("b");
s1.add("a");
s1.add("d");
System.out.println(s1);
TreeSet<Person1> s2 = new TreeSet<Person1>(new MyCompartor());
s2.add(new Person1("成都",5,4));
s2.add(new Person1("天津",4,5));
s2.add(new Person1("北京",5,3));
//重写compareTo方法前
//System.out.println(s2); error,由于采用的有序存放,系统会自动排序,但系统又无法知道如何排序这些对象,因此会出错,这时就需要在类里定义一个排序方法
//重写compareTo方法后
System.out.println(s2);
}
}
//如果要对我们自己定义的对象排序的话该对象必须实现Comparable接口,并通过覆盖compareTo方法,定义排序规则
class Person1 implements Comparable<Person1>{
private String name;
private int age;
private int score;
public Person1(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public Person1() {
}
public String getName() {
return name;
}
public String toString() {
return this.name + this.age + this.score;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int compareTo(Person1 o) {
if(this.age > o.getAge()){
return 1; //返回1则是从小到大,返回-1则是从大到小
}
else if(this.age < o.getAge()){ //当比较一个不足以分辨出前后时,若没有定义比较下一个则会造成存放遗失
return -1;
}
else if(this.score > o.getScore()){ //嵌套一个比较
return 1;
}
else if(this.score < o.getScore()){
return -1;
}
return 0;
}
}
//若是无法更改类为其实现comparable接口时,就需要创建一个Comparator子类实现compare方法,然后在创建TreeSet实例时创建该实例
class MyCompartor implements Comparator<Person1>{
public int compare(Person1 p1,Person1 p2) {
if(p1.getAge() > p2.getAge()){
return 1;
}
else if(p1.getAge() < p2.getAge()){
return -1;
}
else if(p1.getScore() > p2.getScore()){
return 1;
}
else if(p1.getScore() < p2.getScore()){
return -1;
}
return 0;
}
}
```
#SortedSet接口
* 用于排序的接口,它的子类都是排序的,Treeset就是实现了它
```java
public class Collection4 {
public static void main(String[] args) {
SortedSet<String> s = new TreeSet<String>();
s.add("成都");
s.add("天津");
s.add("上海");
s.add("广州");
s.add("桂阳");
System.out.println(s);
System.out.println(s.first()); //查看第一个对象
System.out.println(s.hashCode()); //查询哈希码
System.out.println(s.last()); //查询最后一个对象
System.out.println(s.headSet("广州")); //查询排在此对象前面的对象,不包括此对象
System.out.println(s.tailSet("天津")); //查询排在此对象后面的对象,包括此对象
System.out.println(s.subSet("天津", "成都")); //查询两对象之间的对象,包括前者对象,不包括后者对象
}
}
```
#迭代器
```java
Iterator<Person> ip = list2.iterator(); //迭代器:集合的迭代输出
ListIterator<Person> lip = list2.listIterator(); //若想从后往前输出就必须用Iterator的子接口listIterator,只对List有用
while (ip.hasNext()){ //判断后面是否有元素
//System.out.println(ip.next().getName()); 查看下个元素姓名
//System.out.println(ip.next().getAge()); 若是想查看同一个元素的姓名和年龄,一定不能这么写,因为这行代码代表是下下个元素的年龄了,解决办法就是保存元素
Person p = ip.next();
System.out.print(p.getName());
System.out.print(p.getAge());
}
System.out.println();
while (lip.hasNext()){ //要从后往前必先从前往后
System.out.print(lip.next());
}
System.out.println();
while (lip.hasPrevious()){ //判断前面是否有元素
System.out.print(lip.previous());
}
System.out.println();
```
#Map
* Map接口主要用于查询
```java
Map<String,String> m = new HashMap<String, String>();//创建一个Map,存储的是相对应对象,无序
Map<String,String> m1 = new TreeMap<String,String>();//按照key对数据排序,如果是自己定义的类就必须实现Comparable<>接口
m.put("haoren", "3"); //输入key,value值
m.put("huanren","4");
m.put("buren","2");
System.out.println(m.get("haoren")); //查询key对应的value值
if (m.containsKey("huanren")){ //判断是否有此key存在
System.out.println("有坏人");
}
else{
System.out.println("没有坏人");
}
if (m.containsValue("2")){ //判断是否有此value存在
System.out.println("有2");
}
else{
System.out.println("没有2");
}
Set<Map.Entry<String, String>> s = m.entrySet(); //先要转换成Set
Iterator<Map.Entry<String, String>> it = s.iterator(); //然后调用迭代器进行输出,输出是按一定的标准
while (it.hasNext()){
System.out.println(it.next());
}
List<String> l = new ArrayList<String>(); //为集合添加全部对象
Collections.addAll(l, "haoren" , "huairen", "shangren"); //collections是集合工具类
System.out.println(l);
Collections.reverse(l); //将集合对象反转
System.out.println(l);
Collections.sort(l); //排序
System.out.println(l);
System.out.println(Collections.binarySearch(l, "shangren"));//binarySearch是查找对象位置,调用binarySearch之前, 需对列表进行升序排序sort(all)。如果没有对列表进行排序,则结果是不明确的
Collections.replaceAll(l, "huairen", "haoren");//将指定对象替换成指定对象
System.out.println(l);
Collections.swap(l, 0, 2);
System.out.println(l);//将指定对象互换
```
0 0
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- android studio 配置phone gap应用[英文版]
- 修改 文件上传 默认样式
- Java面试基础概念总结
- Markdown 标记语法
- 暴风魔镜VR项目实战(凝视)
- 泛型
- javascript数组的长度length是可变的
- [php学习二]基本语法练习一
- 属性读写操作小例子
- SQL语句中的or、in、and
- django开发基本步骤
- 多表单同时修改 Freemarker + controller + service
- 抽象类与接口的区别
- org.hibernate.exception.SQLGrammarException:Could not execute JDBC batch update问题的解决