package com.atguigu.javase.generic;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
// 自定义泛型类, A只能是类类型
class Person<A> { // A在这里表示它是某种类型, 类型的形参, 在本类中就可以直接使用A这个类型.
// A类型在创建对象时指定.
// 如果A类型在创建对象时,并未确定的指定, 它就是Object类型, 类型不安全了
// 泛型类型隶属于对象的, 不同的对象在创建时指定的泛型类型可以不一样
private String name;
private A info;
public Person() {
}
public Person(String name, A info) {
super();
this.name = name;
this.info = info;
}
public void setInfo(A info) {
this.info = info;
}
public A getInfo() {
return info;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Person [name=" + name + ", info=" + info + "]";
}
/* 静态成员不可以使用泛型类型
public static void test(A a) {
}*/
/**
* 泛型方法, 方法中的泛型类型在方法的返回值之前声明<泛型的类型参数>
* 泛型方法必须在形参中指定好特定的类型, 否则泛型方法中的泛型类型永远是Object
* 泛型方法中的泛型类型究竟是什么, 由实参来决定.所以是在方法的每一次调用时才能确定的.
* 如果实参是null, 则无法确定泛型类型, 只能是Object类型了.
* @return
*/
public <B> B testB(B b) {
return null;
}
}
class A<X> {
X x;
public X getX() {
return x;
}
}
class B extends A {} // 子类在继承时并未指定X的具体类型, 所以永远是Object
class C extends A<String> {} // 子类在继承时直接写死父类的泛型类型, 在子类中X类型永远是一致,不变的
class C2 extends A<Double> {}
class D<X> extends A<X> {} // 子类在继承父类时仍然保持泛型类型的不确定性.
public class GenericTest {
@Test
public void test6() {
B b = new B();
Object x = b.getX();
C c = new C();
String x2 = c.getX();
D d = new D();
Object x3 = d.getX();
D<Integer> d2 = new D<Integer>();
Integer x4 = d2.getX();
String x5 = new D<String>().getX();
}
@Test
public void test5() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random() * 20));
}
System.out.println(list);
Object[] array = list.toArray();
for (Object object : array) {
System.out.println(object);
}
System.out.println("**********************");
Integer[] array2 = list.toArray(new Integer[] {});
for (Integer integer : array2) {
System.out.println(integer);
}
}
@Test
public void test4() {
Person<String> person = new Person<String>("张三", "北京");
Integer testB = person.testB(30);
String testB2 = person.testB("男");
Boolean testB3 = person.testB(false);
Object testB4 = person.testB(null); // 当实参的类型无法确定时, 泛型方法中的类型就是Object
}
@Test
public void test3() {
List<Integer> list1 = new ArrayList<Integer>();
List<Double> list2 = new ArrayList<Double>();
}
@Test
public void test2() {
// 在这个对象中的A类型就固定是String类型
Person<String> person = new Person<String>("张三", "北京"); // String在创建对象时,会作为类中的A类型的具体类型
String info = person.getInfo();
System.out.println(info);
//person.setInfo(30);
//new Person<Integer>("李四", "上海");
Person<Integer> person2 = new Person<Integer>("李四", 40);
Integer info2 = person2.getInfo();
System.out.println(info2);
}
@Test
public void test1() {
Person person = new Person("张三", 30); // 理论上A类型就是Integer了, 但是没有指定
Object info = person.getInfo();
System.out.println(info);
person.setInfo("男"); // 在这里体现了类型不安全, 因为理论上类型是Integer,但是实际给定的是String
Person person2 = new Person("李四", "女");
Object info2 = person2.getInfo();
System.out.println(info2);
}
}
package com.atguigu.javase.generic;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.junit.Test;
public class GenericTest2 {
public Comparable max(Collection<? extends Comparable> col) {
Iterator<? extends Comparable> iterator = col.iterator();
// 假设第1个数最大
Comparable max = iterator.next();
// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
while (iterator.hasNext()) {
Comparable next = iterator.next();
if (next.compareTo(max) > 0) {
max = next;
}
}
return max;
}
public Comparable min4(Collection<? extends Comparable> col) {
Iterator<? extends Comparable> iterator = col.iterator();
// 假设第1个数最小
Comparable min = iterator.next();
// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
while (iterator.hasNext()) {
Comparable next = iterator.next();
if (next.compareTo(min) < 0) {
min = next;
}
}
return min;
}
// 找出任意集合中的最大值
@Test
public void test8() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random() * 20));
}
System.out.println(list);
System.out.println(min4(list));
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < 10; i++) {
set.add((int)(Math.random() * 20));
}
System.out.println(set);
System.out.println(min4(set));
List<String> list2 = new ArrayList<String>();
list2.add("xxx");
list2.add("abc");
list2.add("YYY");
list2.add("123");
list2.add("来点汉字");
list2.add("你好");
System.out.println(list2);
System.out.println(min4(list2));
}
///
public Number min3(Collection<? extends Number> col) {
Iterator<? extends Number> iterator = col.iterator();
// 假设第1个数最小
Number min = iterator.next();
// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
while (iterator.hasNext()) {
Number next = iterator.next();
if (next.doubleValue() < min.doubleValue()) {
min = next;
}
}
return min;
}
@Test
public void test7() {
List<Integer> list1 = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list1.add((int)(Math.random() * 20));
}
System.out.println(list1);
System.out.println(min3(list1));
List<Float> list2 = new ArrayList<Float>();
for (int i = 0; i < 10; i++) {
list2.add((float)(Math.random() * 20));
}
System.out.println(list2);
System.out.println(min3(list2));
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < 10; i++) {
set.add((int)(Math.random() * 20));
}
System.out.println(set);
System.out.println(min3(set));
}
///
public Number min2(List<? extends Number> list) {
// 假设第1个数最小
Number min = list.get(0);
// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
for (Number number : list) {
if (number.doubleValue() < min.doubleValue()) {
min = number;
}
}
return min;
}
@Test
public void test6() {
List<Integer> list1 = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list1.add((int)(Math.random() * 20));
}
System.out.println(list1);
System.out.println(min2(list1));
List<Float> list2 = new ArrayList<Float>();
for (int i = 0; i < 10; i++) {
list2.add((float)(Math.random() * 20));
}
System.out.println(list2);
System.out.println(min2(list2));
}
///
// 写一个方法 double min(List<????> list)
public double min(List<? extends Number> list) {
// 假设第1个数最小
double min = list.get(0).doubleValue();
// 遍历所有数据, 如果某数据比最小值还小, 刷新最小值
for (Number number : list) {
if (number.doubleValue() < min) {
min = number.doubleValue();
}
}
return min;
}
// 在测试方法中创建两个List集合, 一个保存随机整数, 另一个保存Float型随机数据
@Test
public void test5() {
List<Integer> list1 = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list1.add((int)(Math.random() * 20));
}
System.out.println(list1);
System.out.println(min(list1));
List<Float> list2 = new ArrayList<Float>();
for (int i = 0; i < 10; i++) {
list2.add((float)(Math.random() * 20));
}
System.out.println(list2);
System.out.println(min(list2));
}
public double avg(List<? extends Number> list) {
double sum = 0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum / list.size();
}
@Test
public void test4() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random() * 20));
}
System.out.println(list);
System.out.println(avg(list));
List<Double> list2 = new ArrayList<Double>();
for (int i = 0; i < 10; i++) {
list2.add((Math.random() * 20));
}
System.out.println(list2);
System.out.println(avg(list2));
}
/*public int avg(List<Integer> list) {
int sum = 0;
for (Integer integer : list) {
sum += integer;
}
return sum / list.size();
}*/
@Test
public void test3() {
// 集合中保存的是Number类型及其未知父类 类型范围>= Number
List<? super Number> list = new ArrayList<>();
list.add(200); // 适合添加, 因为它里面可以保存至少是Number类型的对象
list.add(2.5);
Object object = list.get(0); // 不适合于获取, 因为是未知父类
// 集合中保存的是Number类型及其未知子类类型, 类型范围 <= Number
List<? extends Number> list2 = new ArrayList<>();
//list2.add(200); // 不可以添加元素, 因为具体的子类类型是未知的. 不可以冒然添加元素
//list2.add(2.8);
Number number = list2.get(0); // 适合于获取, 因为最多就是Number.
}
/**
* 此方法对于集合的访问是只读的, 更安全
* @param col
*/
public void travel(Collection<?> col) {
for (Object object : col) {
System.out.println(object);
}
}
@Test
public void test2() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random() * 20));
}
travel(list);
}
@Test
public void test1() {
List<Integer> list1 = new ArrayList<Integer>();
//List<Number> list2 = new ArrayList<Integer>(); // 原因是左侧的集合中保存的是范围更大的类型.
// List<?>list 集合只能获取, 不能添加, 所以适用于只读访问.
List<?> list2 = new ArrayList<Integer>(); // ?表示未知类型, 范围不确定
//list2.add(100); // 绝对不可以... 因为集合中的类型未知, 不可以冒然添加
//list2.add(new Object());
list2.add(null); // 因为null不表示任何类型
Object object = list2.get(0);
List<Object> list3 = new ArrayList<Object>();
list3.add(200);
}
}