线程
创建线程的方式;
- 继承Thread类,覆盖run()方法;
- 使用:创建线程对象,然后调用对象.start()方法(注意,不是调用run()方法);
- 实现Runnable接口,实现run()方法;
- 使用:创建线程对象,然后创建Thread对象并传入线程对象,调用Thread对象.start()方法
操作线程的方式
-
//sleep方法 Thread.sleep(毫秒)
-
//可以获取到当前线程的对象 Thread.currentThread()
-
//将线程设为后台线程 线程对象.setDaemon(true);
-
//每个线程都有优先级,优先级的高低只和线程获得执行机会的次数多少有关。 //并不是说优先级高的就一定先执行,哪个线程的先运行取决于CPU的调度; Thread对象.setPriority(int x) //和getPriority()用来设置和获得优先级。
同步锁
-
//同步代码块 synchronized(同步锁){//锁为一个公共的对象 //需要锁的代码 }
-
//同步方法 //用synchronized修饰方法,注意不能用来修饰run()方法 //否则一个进程抢到了,其他进程就不能抢了 private synchronized void eat(){ //方法主体 }
集合体系
ArrayList
-
基于数组的集合
-
//创建ArrayList对象 List list = new ArrayList(); //添加元素 list.add("A"); list.add("B"); list.add("C"); list.add("A"); list.add("B"); list.add("C"); //在指定索引处插入,效率低 list.add(2,"B"); //修改制定索引的元素 list.set(1,"X"); //删除元素 list.remove(2); list.remove("A"); //删除所有 //list.removeAll(list); //查询元素 list.get(1); //打印接元素个数 System.out.println(list.size()); System.out.println(list); //集合-->数组 list.toArray(); //数组-->集合 List l = Arrays.asList(new Object[]{1, 2, 3, 4, 5, 6}); List l2 = Arrays.asList(1, 2, 3, 4, 5, 6);
LinkedList
-
基于链表的集合
-
有着List接口的方法跟特有的操作首尾元素的方法
-
//创建LinkedList对象 LinkedList<String> list = new LinkedList<>(); //在头尾加 list.addFirst("E"); list.addLast("F"); //取首尾元素 String first = list.getFirst(); String last = list.getLast(); //移除并返回前后元素 list.removeFirst(); list.removeLast();
-
List各大数据结构特点
- ArrayList:数组结构,增删慢,改查快
- LinkedList:链表结构,增删快,改查慢
- Queue:队列结构,先进先出,擅长操作头尾,不允许操作中间
- Stack :栈,后进先出,(类似一端封死)只能往上叠加,移除栈顶,查询栈顶的对象,查询对象在栈中的位置
泛型
-
泛型的定义
-
//<T>:声明一种泛型类型 //常用的泛型字母: T:type:类型 E:element:元素 K:key V:value public class Point<T> { private T x; private T y; //省略getter和setter方法 }
-
-
泛型的使用
-
//用户想用Integer来表示坐标 Point<Integer> p = new Point<Integer>(); //钻石语法 菱形语法 Point<Integer> p3 = new Point<>(); p.setX(10); p.setY(100); //用户需求变了,想用String来表示坐标 Point<String> p2 = new Point<String>(); //钻石语法 菱形语法 Point<String> p4 = new Point<>(); p2.setX("123"); p2.setY("13");
-
-
注意
- 泛型其实是语法糖,也就是说编译之后,泛型就不存在了,底层会帮我们做强转
- 泛型必须引用类型,不能是基本类型
- 泛型不存在继承关系
迭代/遍历
Set集合
- 不允许元素重复
- 不会记录元素的先后添加顺序
- 实现了Collection接口
HashSet
其实也是个数组,底层采用哈希算法,value的哈希值来决定在哈希表中的存储位置
-
擅长做等值查询
-
HashSet如何比较两个对象是否相同
- 两个对象的equals相等,返回true,则说明是相同对象
- 两个对象hashCode方法返回值相等
-
当往HashSet添加对象的时候,先判断hashCode值
- 不等:直接把新的对象存储到hashCode的指定位置
- 相等:再继续判断新对象和集合中的对象中equals作比较
- 相同:视为同一对象,则不保存在哈希表中
- 不同:非常麻烦,存储在之前对象的同槽位的链表上
TreeSet
- 红黑树算法
- 擅长做范围查询
LinkedHashSet
-
HashSet的子类
-
底层采用哈希表和链表算法
-
不允许元素重复
-
会记录元素的先后添加顺序
Map(映射关系)
Map接口没有继承于Collection接口
HashMap
采用哈希表算法,此时Map中的key不会保证添加的先后顺序,key也不允许重复
- key判断重复的标准:equals为true,并且hashCode相等
TreeMap
采用红黑树算法,此时Map中的key会按照自然顺序或者定制排序进行排序,key不允许重复
- key判断重复的标准:compare To/compare的返回值为0
LinkedHashSet
采用链表和哈希表算法,此时Map中的key会保证先后的添加顺序,key也不允许重复
- key判断重复的标准:equals为true,并且hashCode相等
Hashtable
采用哈希表算法,是HashMap的前身(类似于Vector是ArrayList的前身),线程安全
Properties
Hashtable的子类,此时要求key和value都是String类型
用来加载资源文件Properties文件
//获取Map对象
HashMap<String, Object> map = new HashMap<>();
//添加键值对
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
map.put("key5","value5");
System.out.println(map);
//map.clear();//清除整个Map
System.out.println(map.containsKey("key1"));//检查是否有这个key
System.out.println(map.containsValue("value2"));//检查是否有这个value
System.out.println(map.get("key2"));//按照key找value
System.out.println(map.size());//查询Map键值对的数量
map.remove("key5");//按照key删除对应的键值对
System.out.println(map);
//获取Map中所有key所组成的集合(key是不能重复的,类似于set)
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key + "-->" + map.get(key));
}
//获取Map中所有value所组成的集合(value是不能重复的,类似于List)
Collection<Object> values = map.values();
for (Object value : values) {
System.out.println(value);
}
//获取Map中所有的Entry(key-value)
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> entry : entries) {
String key = entry.getKey();//获取key
Object value = entry.getValue();//获取value
System.out.println(key + "<->" + value);
}
Collections工具类
//返回线程同步的集合对象
List<Object> list = Collections.synchronizedList(List对象);
Set<Object> set = Collections.synchronizedSet(Set对象);
Map<String,Object> map = Collections.synchronizedMap(Map对象);
I/O
反射
Lambda
JavaBean
内省机制
-
public class User { private String name; private int age; private boolean man; //省略getter/setter方法 } }
-
//获取Javabean的描述对象 BeanInfo beanInfo = Introspector.getBeanInfo(User.class,Object.class); User user = User.class.newInstance();//利用反射创建user对象 System.out.println(user); //获取javaBean中的属性描述器 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { //获取当前属性的名称 System.out.println("属性名="+pd.getName()); //获取当前属性的getter方法 System.out.println("getter="+pd.getReadMethod()); //获取当前属性的setter方法 System.out.println("setter="+pd.getWriteMethod()); System.out.println("----------------------------------------"); if("name".equals(pd.getName())){ Method setter = pd.getWriteMethod(); setter.invoke(user,"will");//利用反射调用方法 参数1:user对象 参数2:传给调用方法的参数 System.out.println(user); }
JavaBean和Map之间的转换
-
//把Javabean转换为Map public static Map<String,Object> bean2map(Object bean) throws Exception { HashMap<String, Object> map = new HashMap<>(); BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { String key = pd.getName();//key Method readMethod = pd.getReadMethod();//获取属性的getter方法 Object value = null;//初始化value if (readMethod != null) {//判断属性是否有getter方法 value = readMethod.invoke(bean);//获取属性对应的值并赋值给value } map.put(key,value);//把k y对添加进map } return map; }
-
//把Map转化为JavaBean public static <T> T map2bean(Map<String,Object> map, Class<T> beanType) throws Exception { //创建对象 T obj = (T)beanType.newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(beanType.getClass(), Object.class); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { Object value = map.get(pd.getName());//按照属性名找Map里对应的值 Method writeMethod = pd.getWriteMethod();//获取setter方法 if (writeMethod != null){//判断是否有setter方法 writeMethod.invoke(obj,value);//设置属性值 } } return obj; }
Apache Commons
注解
注解的定义语法
-
@Target(ElementType.TYPE) //标识注解可以贴在类上/接口上 @Retention(RetentionPolicy.RUNTIME)//标识注解可以存在于jvm中(通过反射赋予功能) public @interface 注解名称 { //抽象方法 -->属性 //返回类型 方法名称(); }
-
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface VIP { String value(); int age() default 18;//default 默认值 }
获取程序元素上的注解
-
@VIP(value = "xx",age = 18) public class Employee { }
-
public class VIPDemo { public static void main(String[] args) { //需求:获取Employee上所有的注解 //1.获取Employee字节码对象 Class<Employee> clz = Employee.class; //2.直接获取类上所有的注解 /* Annotation[] as = clz.getAnnotations(); for (Annotation a : as) { System.out.println(a);//@cn.kongbai._05_anno.VIP(age=18, value=xx) }*/ //判断employee类上是否使用VIP注解 VIP a = clz.getAnnotation(VIP.class); if (a==null){ System.out.println("没有"); }else { System.out.println("有"); System.out.println(a.value());//xx System.out.println(a.age());//18 } } }
XML解析
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
<student id="s1">
<name>lisi</name>
<age>17</age>
</student>
<student id="s2">
<name>wangwu</name>
<age>19</age>
</student>
</students>
private File file = new File("src/cn/kongbai/_04_dom/student.xml");
@Test//修改
public void test() throws Exception {
//获取Document对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
//==================================================
//获取xml根元素
Element root = doc.getDocumentElement();
System.out.println(root);
//获取第二个student元素
Element student1 = (Element) doc.getElementsByTagName("student").item(1);//对于文档中
Element student = (Element) root.getElementsByTagName("student").item(1);//对于root中
System.out.println(student);
//获取所有的name元素
Element name =(Element) student.getElementsByTagName("name").item(0);
//获取name元素的文本内容
System.out.println(name.getTextContent());
//获取age元素
Element age = (Element) student.getElementsByTagName("age").item(0);
//设置age为19
age.setTextContent("19");
//同步操作(使用核心类:Templates)
TransformerFactory factory = TransformerFactory.newInstance();
Transformer trans = factory.newTransformer();
DOMSource domSource = new DOMSource(doc);//源:内存中的Document对象
StreamResult streamResult = new StreamResult(file);//目标磁盘中的xml文件
trans.transform(domSource,streamResult);//同步操作
}
@Test//添加
public void test1() throws Exception {
//获取Document对象
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
//获取xml根元素
Element root = doc.getDocumentElement();
//==================================================
//创建元素
Element student = doc.createElement("student");
Element name = doc.createElement("name");
Element age = doc.createElement("age");
//设置文本内容
name.setTextContent("mihap");
age.setTextContent("20");
//设置属性
student.setAttribute("id", "s3");
//把name age设置为student的子元素
student.appendChild(name);
student.appendChild(age);
//把student设置为students的子元素
root.appendChild(student);
//==================================================
//同步操作
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(doc),new StreamResult(file));
}
@Test//删除
public void test2() throws Exception {
//获取Document对象
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
//获取xml根元素
Element root = doc.getDocumentElement();
//第三个student
Element student = (Element) root.getElementsByTagName("student").item(2);
//==================================================
// root.removeChild(student);//删除子元素
student.getParentNode().removeChild(student);//找到父元素.删除自己
//==================================================
//同步操作
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(doc),new StreamResult(file));
}
@Test//创建Document对象
public void test3() throws Exception {
File f = new File("故意写错的.xml");
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = null;
//如果xml文件存在则加息,否则创建新的
if (f.exists()){//文件存在
doc = builder.parse(f);//创建
}else {//文件不存在
doc = builder.newDocument();//在内存中创建Document对象
//创建根元素,并把根元素作为文档的子元素
Element root = doc.createElement("根元素名");
doc.appendChild(root);
}
//保存元素,然后同步
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(doc),new StreamResult(f));
}
评论区