泛型
泛型是编译期行为,只能在编译期有效,泛型又分为泛型类,泛型方法,泛型接口。
泛型类:
定义:在类名后加<>括号中编写任意长度任意字符,但是不能是数值,通常是写26个大写字母
使用:泛型类<具体类型> 变量名=new 泛型类<>();
泛型方法:
定义:在方法中使用泛型,非静态方法是在参数中写和类相同的泛型
使用:public static <泛型类型> void 方法名(){}
tips:静态方法无法使用泛型类中声明的泛型类型,因为泛型类型的确定是创建对象时确定的,而静态方法是先于对象存在的,如果要使用,在当前静态方法上声明泛型类型
泛型接口:
实现类实现泛型接口时不指定泛型类型,则创建对象时可以指定泛型类型
class UserImpl implements User
实现类实现泛型接口时指定泛型类型,
class UserImpl implements User
public class Test01 {
public static void main(String[] args) {
Genric<String> g=new Genric<String>();
g.add("sss");
Genric g1=new Genric();
g1.add("123");
g1.add(1);
}
}
class Genric<E>{
public void add(E e) {
}
}
interface User<T>{
public void fun(T t) ;
}
class UserI<T> implements User<T>{
public void fun(T t) {
}
}
反射
反射是运行期行为,就是把java类中的各种成分映射成一个个的Java对象
class类:这个类产生的一个实例对象用来描述某个类。 class 这个class对象描述的就是Person类。所有的Person的对象和Person类共享 当前该class对象.
获取class对象的方法:
- Class.forName(需要获取类的全限定名)
- 类名.class
- 对象.getclass
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
//获取一个类的class对象方法
Class c=Class.forName("java.lang.String");
System.out.println(c);
//获取String的class对象
Class c1=String.class;
System.out.println(c==c1);
//获取String对象对应的hclass对象
Class c2="万".getClass();
Class c3="刘".getClass();
System.out.println(c2==c3);
}
}
获取属性,方法,构造器
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
//获取User的class对象
Class c=Class.forName("com.mage.ref.User");
//获取属性
System.out.println("获取public修饰的指定的属性");
Field f=c.getField("id");
System.out.println(f.getName()+"==="+f.getType()+"==="+Modifier.toString(f.getModifiers()));
System.out.println("获取public修饰的所有属性");
Field[] f1=c.getFields();
for (Field f2 : f1) {
System.out.println(f2.getName()+"==="+f2.getType()+"===="+Modifier.toString(f2.getModifiers()));
}
System.out.println("获取指定字段的属性");
Field f3=c.getDeclaredField("name");
System.out.println(f3.getName()+"==="+f3.getType()+"===="+Modifier.toString(f3.getModifiers()));
System.out.println("获取所有字段的属性");
Field[] f4=c.getDeclaredFields();
for (Field f5 : f4) {
System.out.println(f5.getName()+"==="+f5.getType()+"===="+Modifier.toString(f5.getModifiers()));
}
System.out.println("获取public修饰的指定方法");
Method m=c.getMethod("fun", int.class,String.class);
System.out.println(Modifier.toString(m.getModifiers())+"===="+m.getParameterCount()+"==="+m.getName());
System.out.println("获取public修饰的所有方法(包含父类)");
Method[] m1=c.getMethods();
for (Method m2 : m1) {
System.out.println(Modifier.toString(m2.getModifiers())+"===="+m2.getParameterCount()+"==="+m2.getName());
}
System.out.println("获取指定的非public修饰的方法");
Method m3=c.getDeclaredMethod("method", Integer.TYPE,String.class);
System.out.println(Modifier.toString(m3.getModifiers())+"===="+m3.getParameterCount()+"==="+m3.getName());
System.out.println("获取所有方法,不包含父类");
Method[] m4=c.getDeclaredMethods();
for (Method method : m4) {
System.out.println(Modifier.toString(method.getModifiers())+"===="+method.getParameterCount()+"==="+method.getName());
}
System.out.println("获取构造器public修饰的");
Constructor con=c.getConstructor(null);
System.out.println(con.getName()+"==="+con.getParameterCount());
System.out.println("获取构造器非public");
con=c.getDeclaredConstructor(Integer.TYPE,String.class,Integer.TYPE,Integer.TYPE);
System.out.println(con.getName()+"==="+con.getParameterCount());
System.out.println("获取所有构造器");
Constructor[] con1=c.getConstructors();
for (Constructor con2 : con1) {
System.out.println(con.getName()+"==="+con.getParameterCount());
}
System.out.println("获取所有非public的构造器");
Constructor[] con3=c.getDeclaredConstructors();
for (Constructor con4 : con3) {
System.out.println(con4.getName()+"==="+con4.getParameterCount());
}
}
}
List
List接口是Collection的子接口,有序,可重复的,也可以是null
定义:public interface List extends Collection
方法:
增加:add(index,obj) add(obj) addAll(coll) addAll(index,coll)
修改:set(index,obj)
删除:remove(index,obj) removeAll(coll) retainAll(coll) clear()
查看:isEmpty() contains(obj) size() containsAll() get() indexOf(obj) lastIndexOf(obj) subList(sindex,eindex)
import java.util.List;
import java.util.ArrayList;
public class Test03 {
public static void main(String[] args) {
//创建对象
List list=new ArrayList();
//添加元素
list.add("ncc");
List c=new ArrayList();
c.add("ss");
c.add("sd");
//添加集合
list.addAll(c);
//删除元素
list.remove(0);
list.remove(Integer.valueOf(1));
//修改元素
list.set(1, "sdaa");
System.out.println("是否为空:"+list.isEmpty());
System.out.println("查看指定位置上的元素:"+list.get(0));
}
}
迭代:普通for foreach() 迭代器(iterator[不能支持并发修改] listIterator[支持并发修改])
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test04 {
public static void main(String[] args) {
//创建对象
List l=new ArrayList();
//添加元素
l.add("嘻嘻");
l.add("呵呵");
l.add("哼哼");
l.add("哈哈");
System.out.println("普通for循环");
for(int i=0;i<l.size();i++) {
System.out.println(l.get(i));
}
System.out.println("foreach循环");
for (Object obj: l) {
System.out.println(obj);
}
System.out.println("迭代器");
Iterator it=l.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
ArrayList
List接口的实现类,实际上ArrayList是一个动态数组
优缺点:通过索引获取元素和迭代元素速度比较快,但是添加和删除元素时速度慢
方法:与List方法一致
迭代:与List一致
LinkedList
List接口的实现类,实际上LinkedList是双向链表
优缺点:与ArrayList刚好相反,添加,删除元素速度快,但获取和迭代元素慢
方法:与List方法一致,还多了一些头尾操作
查看:
增加:add(index,obj) add(obj) addAll(coll) addAll(index,coll)
offer() offerFirst() offerLast() addFirst() addLast()
修改:set(index,obj)
删除:remove(index,obj) removeAll(coll) retainAll(coll) clear()
poll () pollFirst() pollLast() removeFirst () removeLast()
查看:isEmpty() contains(obj) size() containsAll() get() indexOf(obj) astIndexOf(obj)
subList(sindex,eindex) getFirst() getLast() element() peekFirst () peekLast()
import java.util.LinkedList;
//编写LinkedList
public class Test08 {
public static void main(String[] args) {
LinkedList<String> l=new LinkedList<String>();
//添加元素
l.add("花木兰");
l.add("曹操");
l.add("孙策");
l.add(1,"赵子龙");
System.out.println(l);
//添加到首位
l.addFirst("吕布");
l.offerFirst("刘备");
System.out.println(l);
//添加到末位
l.addLast("貂蝉");
l.offerLast("香香");
System.out.println(l);
//获取头元素
System.out.println(l.element());
System.out.println(l.getFirst());
//获取尾元素
System.out.println(l.getLast());
//查看第一个元素
System.out.println(l.peekFirst());
//查看最后一个元素
System.out.println(l.peekLast());
}
}
Set
Set接口是Collection的子接口,是无序的,唯一的
定义:public interface Set extends Collection
方法:
增加:add() addAll()
删除:remove() removeAll() retainAll() clear()
查看:isEmpty() contains() size() containsAll() iterator
HashSet
Set接口的实现类,首先是无序的,不可重复的,允许存放null值
方法:
add(E e) : 如果此 set 中尚未包含指定元素,则添加指定元素
isEmpty(): 如果此 set 不包含任何元素,则返回 true
contains(Object o): 如果此列表中包含指定的元素,则返回 true
size() : 返回此 set 中的元素的数量(set 的容量)
clear() :移除此列表中的所有元素
remove(Object o):如果指定元素存在于此 set 中,则将其移除
iterator:迭代器
tips:要想在hashSet集合中实现元素存取的唯一性,由于底层判断依赖于equals和hashCode方法,故所存取的元素需要重写这两个方法,以按照我们的期待存取元素。保证元素唯一性。
import java.util.HashSet;
public class Test01 {
public static void main(String[] args) {
//创建hashset
HashSet<User> set=new HashSet<>();
set.add(new User(1888,"曹操"));
set.add(new User(3999,"皇子"));
set.add(new User(12333,"庄周"));
System.out.println(set);
}
}
class User{
private int money;
private String name;
public User() {}
public User(int money,String name) {
super();
this.money=money;
this.name=name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + money;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (money != other.money)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "User [money=" + money + ", name=" + name + "]";
}
}
TreeSet
Set接口的实现类,底层是树,TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
优缺点:有利于维护数据的大小,添加和删除元素的速度高于ArrayList,低于其他;查询速度高于list低于hash
常见方法:
添加:add() addAll()
删除:remove() removeAll() retainAll() clear()
查询:size() isEmpty() contains() containsAll()
last():获取最大元素
first():获取最小元素
celling():查找大于等于给定元素的最小值
higher():查找大于给定元素的最小值
floor():查找小于或等于给定元素的最大值
lower():查找小于给定元素的最大值
迭代方法:foreach,迭代器
tips:1.如果存储的元素要按指定的需求排列顺序,创建TreeSet对象,指定比较器
2.如果存储的元素是对象:要么对象的所属类实现了内部比较器Comparable接口,重写compareTo方法
要么创建TreeSet对象时,指定外部比较器接口Comparetor,重写compare方法
import java.util.Iterator;
import java.util.TreeSet;
public class Test02 {
public static void main(String[] args) {
TreeSet<String> treeSet =new TreeSet<String>();
//添加
treeSet.add("a");
treeSet.add("b");
treeSet.add("c");
treeSet.add("r");
treeSet.add("t");
System.out.println(treeSet);
//查找
System.out.println("查找大于或等于给定元素的最小值:"+treeSet.ceiling("c"));
System.out.println("查找大于给定元素的最小值:"+treeSet.higher("c"));
System.out.println("获取最大元素:"+treeSet.last());
System.out.println("获取最小元素:"+treeSet.first());
System.out.println("查找小于或等于给定元素的最大值:"+treeSet.floor("c"));
System.out.println("查找小于给定元素的最大值:"+treeSet.lower("c"));
for(String str:treeSet) {
System.out.println(str);
}
Iterator it=treeSet.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}