【Java基础27】泛型,正则表达式,枚举,注解,XML

一、泛型

使用泛型可以使集合记住集合内元素的类型,且能够达到只要编译时不出现问题,运行时就不会有异常。

泛型只作用于代码编译阶段。

泛型上限指一个操作泛型最大的操作父类,例如上限为“Number”,所能接收到的类型只能是Number和子类。

泛型下限指的是只能设置其具体的类或者父类。

package generic;

import org.junit.Test;

import java.util.*;

public class Generic {
    @Test
    public void test05(){
        Map<Integer,String> map=new HashMap<>();
        map.put(1,"lili");
        map.put(2,"haha");
        //泛型嵌套
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        for(Map.Entry entry: entrySet){
            System.out.println(entry.getKey()+"---"+entry.getValue());
        }
    }

    @Test
    public void test04(){
        String[] arrays={"1","2","3"};
        func(arrays,0,1);
        System.out.println(Arrays.toString(arrays));
    }

    //泛型方法
    public static <T> T[] func(T[] array,int i,int t){//T---返回类型
        //交换
        T temp=array[i];
        array[i]=array[t];
        array[t]=temp;

        return array;
    }

    @Test
    public void test03(){
        Node<Number> node1=new Node<Number>(10);
        Node<Integer> node2=new Node<Integer>(20);
        Node<Double> node3=new Node<Double>(30.0);
//        getData(node1);
//        getData(node2);//node2与node类型不匹配,不能传递
//        getData1(node1);
//        getData1(node2);
//        getUpperNumberData(node1);
//        getUpperNumberData(node2);
//        getDownerNumberData(node1);
//        getDownerNumberData(node2);
//        node3是Double类型,超出Integer类型,报错
//        getDownerNumberData(node3);
    }

    public static void getData(Node<Number> node){
        node.setData(1);
        System.out.println(node.getData());
    }
    //使用通配符,解决类型不匹配问题
    public static void getData1(Node<?> node){
//        node.setData(1);//?--不知道参数是什么类型,不能进行修改
        System.out.println(node.getData());
    }

    //设置泛型上限
    public static void getUpperNumberData(Node<? extends Number> node){
        System.out.println(node.getData());
    }

    //设置泛型下限
    public static void getDownerNumberData(Node<? super Integer> node){
        System.out.println(node.getData());
    }


    @Test
    public void test02(){
        Node<Integer> node1=new Node<Integer>(18);
        System.out.println(node1.getData());

    }
    @Test
    public void test01(){
        List<String> list=new ArrayList<>();
        list.add("周日");
//        list.add(18);
//        list.add(new Object());
        for (int i = 0; i < list.size(); i++) {

        }
    }
}



//自定义泛型类
package generic;
public class Node<T>{
    private T data;

    public Node() {
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Node(T data) {
        this.data = data;
    }
}

二、正则表达式

package regex;

import org.junit.Test;

import java.sql.SQLOutput;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//正则表达式
public class Regex{
    @Test
    public void test1(){
        String s="5201314";
        boolean matches = s.matches("[0-9]+");//[0-9]----表示一个字符的范围,+----表示多个字符
        boolean matches1 = s.matches("\\d+");//更多匹配方法参考API文档
        System.out.println(matches);
        System.out.println(matches1);
    }

    //创建一个匹配模式
    @Test
    public void test(){
        Pattern p=Pattern.compile("a*b");//a*-----aaaaaaaa,*---多个,其他参考API文档
        Matcher matcher=p.matcher("aaaaaab");//true
//        Matcher matcher1=p.matcher("aaa234bbbbhgfb");//false
        boolean b=matcher.matches();
        System.out.println(b);
    }

}

三、枚举

枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则编译器就会报错,枚举可以让编译器在编译时就可以控制源程序赋给的非法值,使用普通变量的方式在开发阶段无法实现这一目标。

//接口
public interface Info {
    public int  getColor();
}

//枚举定义单例
public enum Singleton {
    SINGLETON;
    public void method(){
        System.out.println("method方法");
    }
}

//枚举
public enum Color implements Info {
    RED{
        @Override
        public String getColor1() {
            return "red";
        }
    },GREEN {
        @Override
        public String getColor1() {
            return "green";
        }
    },BLUE {
        @Override
        public String getColor1() {
            return "blue";
        }
    },BLACK(1) {
        @Override
        public String getColor1() {
            return "black";
        }
    };
    private int color;
    Color(){
        System.out.println("无参构造方法");
    }//枚举构造函数不能是public型
    Color(int color){
        this.color=color;
        System.out.println("有参构造方法");
    }

    public int  getColor() {
        return color;
    }

    //可以定义抽象方法
    public abstract String getColor1();
}

//实现类
import org.junit.Test;

import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;

public class EnumDemo{
    public static final int RED=0x1;
    public static final int GREEN=0x2;
    public static final int BLUE=0x3;
    public int color;

    public Color colorEnum;

    //使用枚举实现单例模式
    @Test
    public void test5(){
        Singleton.SINGLETON.method();
    }

    @Test
    public void test4(){
        System.out.println(Color.RED);//依次调用每个类型
        System.out.println(Color.RED.getColor());
    }

    @Test
    public void test3(){
//        EnumSet<Color> es=new EnumSet<>(){}//抽象类,需要实现方法
        EnumSet<Color> es=EnumSet.allOf(Color.class);
        for(Color c:es){
            System.out.println(c);
        }

        EnumMap<Color,String> em=new EnumMap<Color, String>(Color.class);
        em.put(Color.RED,"red");
    }

    @Test
    public void test2(){
        colorEnum=Color.RED;//枚举型
        System.out.println(colorEnum);//RED
        System.out.println(colorEnum.ordinal());//序号

        Color[] values = Color.values();//枚举类型的值
        System.out.println(Arrays.toString(values));
    }

    @Test
    public void test1(){
        color=RED;
        color=2;

    }



}

四、注解

代码里做的特殊标记,这些标记可以在编译、类加载、运行时在不改变原有逻辑的情况下,被读取,并执行相应的处理。

Annotation类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数、局部变量的声明。

Annotation是一个接口,java.lang.Annotation接口

//系统提供的三种注解:
@Override @Deprecated  @SuppressWarnings

//测试类
package annotation;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class AnnotationDemo {
    @Test
    public void test1(){
        Cat cat=new Cat("huahua",2);
        cat.printInfo();//横线,代表调用了一个已过时的方法

        @SuppressWarnings("all")//消除警告信息
        List list=new ArrayList();
        list.add("vince");
        list.add(10);
        list.add(10.0);
    }
}


//实体类
package annotation;

public class Cat {
    private String name;
    private int age;

    @Override//用于验证方法是否是覆盖了父类中的方法
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Deprecated//用于标记方法已过时,不建议使用
    public String printInfo(){
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Cat() {
    }
}

自定义注解:

1.编写注解

2.在类上应用注解

3.对 应用了注解的类 进行反射 操作的类

//自定义注解
package annotation;

import java.lang.annotation.*;
import java.lang.reflect.Type;

@Documented//注解的注解,生成DOC文档时使用,注释的注解
@Retention(RetentionPolicy.RUNTIME)//作用范围在运行时,注释注解
@Target(ElementType.TYPE)//表示Annotation的应用范围(类型,方法,属性等)
@Inherited//表示Annotation可以被子类继承
public @interface MyAnnotation {
    //定义变量
    public String name();//变量
    public int age() default 2;//定义默认值,使用注解时可以不赋值
    public String[] like();//只进行定义
    public Color color();//定义一个枚举类型变量
}


//测试类
package annotation;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

public class AnnotationDemo {
    //反射处理注解
    @Test
    public void test2(){
        Class<Cat> catClass = Cat.class;
        //获取类上应用的指定注解
        MyAnnotation annotation = catClass.getAnnotation(MyAnnotation.class);
        //获取注解上的变量值
        String name = annotation.name();
        int age = annotation.age();
        Color color = annotation.color();
        String[] like = annotation.like();
        //实例化对象
        try {
            Cat cat = catClass.newInstance();
            cat.setName(name);
            cat.setAge(age);
            cat.setColor(color);
            cat.setLike(like);
            System.out.println(cat);

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

}

//枚举类
package annotation;

public enum Color {
    RED,GREEN,YELLOW;
}

//实体类
package annotation;

import java.util.Arrays;

@MyAnnotation(name = "haha",like = {"111","222"},color = Color.RED)
public class Cat {
    private String name;
    private int age;
    private String[] like;
    private Color color;

    public String[] getLike() {
        return like;
    }

    public void setLike(String[] like) {
        this.like = like;
    }



    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", like=" + Arrays.toString(like) +
                ", color=" + color +
                '}';
    }

    @Deprecated//用于标记方法已过时,不建议使用
    public String printInfo(){
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Cat(String name, int age, String[] like, Color color) {
        this.name = name;
        this.age = age;
        this.like = like;
        this.color = color;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Cat() {
    }
}

五、XML

XML(Extensible Markup Language可扩展标记语言)

XML是一个以文本来描述数据的文档。

XML技术的用途:

  • 充当显示数据(以XML充当显示层)
  • 存储数据(存储层)的功能
  • 以XML描述数据,并在联系服务器与系统的其余部分之间传递

从某种角度讲,XML是数据封装和消息传递技术。

掌握XML的解析方法是核心:SAX和DOM

1、SAX解析

//SAX解析

//Person.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<people>
    <person personid="E01">
        <name>Tony</name>
        <address>10 Downing Street,London,UK</address>
        <tel>98765</tel>
        <fax>98765</fax>
        <email>tony@everywhere.com</email>
    </person>
    <person personid="E02">
        <name>Bill</name>
        <address>White House,USA</address>
        <tel>(001) 6400 98765</tel>
        <fax>(001) 6400 98765</fax>
        <email>bill@everywhere.com</email>
    </person>
</people>
    
    
//实体类
    package xml;

public class Person {
    private String personid;
    private String name;
    private String address;
    private String tel;
    private String fax;
    private String email;

    @Override
    public String toString() {
        return "xml.Person{" +
                "personid='" + personid + '\'' +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", tel='" + tel + '\'' +
                ", fax='" + fax + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

    public String getPersonid() {
        return personid;
    }

    public void setPersonid(String personid) {
        this.personid = personid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getFax() {
        return fax;
    }

    public void setFax(String fax) {
        this.fax = fax;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Person(String personid, String name, String address, String tel, String fax, String email) {
        this.personid = personid;
        this.name = name;
        this.address = address;
        this.tel = tel;
        this.fax = fax;
        this.email = email;
    }

    public Person() {

    }
}

//SAX解析类
package xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.List;


public class PersonHandler extends DefaultHandler {
    //解析文档变成对象,两个对象使用集合存储
    private List<Person> list=null;
    private Person p;//当前正在解析的对象
    private String tag;//用于记录当前正在解析的标签名

    public List<Person> getList() {
        return list;
    }

    //开始解析文档时调用
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        list=new ArrayList<>();
        System.out.println("开始解析文档...");
    }

    //XML文档解析结束时调用
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("解析文档结束!");
    }

    /*uri:命名空间
    * localName:不带前缀的标签名<Person>
    * qName:带前缀的标签名<aa:Person>
    * attributes:当前标签的属性集合
    * */
    //解析开始元素时调用,例如标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if("person".equals(qName)){
            p=new Person();
            String personid = attributes.getValue("personid");
            p.setPersonid(personid);
        }
        tag=qName;
        System.out.println("startElement-----"+qName);
    }

    //解析结束元素时调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if ("person".equals(qName)) {
            list.add(p);
        }
        tag=null;
        System.out.println("startElement-----"+qName);
    }

    //解析文本内容时调用
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        if(tag!=null){
            if("name".equals(tag)){
                p.setName(new String(ch,start,length));
            }else if("address".equals(tag)){
                p.setAddress(new String(ch,start,length));
            }else if("tel".equals(tag)){
                p.setTel(new String(ch,start,length));
            }
            else if("fax".equals(tag)){
                p.setFax(new String(ch,start,length));
            }
            else if("email".equals(tag)){
                p.setEmail(new String(ch,start,length));
            }
            System.out.println(ch);
        }
    }
}

//测试类
package xml;

import javafx.scene.media.VideoTrack;
import org.junit.Test;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class XMLDemo {
    
/*SAX解析:
1、基于事件驱动
2、顺序读取,速度快
3、不能任意读取节点,灵活性差
4、解析时占用的内存小
5、SAX更适用于性能要求更高的的设备上使用
*/
    
    @Test
    public void test1() throws ParserConfigurationException, SAXException, IOException {
//        1、创建一个SAX解析器工厂对象
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//        2、通过工厂对象创建SAX解析器
        SAXParser saxParser = saxParserFactory.newSAXParser();
//        3、创建一个数据处理器(需要我们自己编写)
        PersonHandler personHandler = new PersonHandler();
//        4、开始解析
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("xml/Person.xml");
        saxParser.parse(is,personHandler);
        List<Person> list = personHandler.getList();
        for(Person p:list){
            System.out.println(p);
        }
    }

}

2、DOM解析

/* DOM解析:
1、基于树形结构
2、通过解析器一次性把文档加载到内存中,比较占用内存
3、可以随机访问,更加灵活,更适合WEB开发中使用
*/
    @Test
    public void domParseXML() throws ParserConfigurationException, IOException, SAXException {
        //1、创建一个DOM解析器工厂类对象
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //2、通过工厂对象创建解析器对象
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //3、解析文档
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("xml/Person.xml");
        //此代码完成后,整个XML文档已经被加载到内存中,以数状形式存储
        Document parse = documentBuilder.parse(is);
        //4、从内存中读取数据

        //获取节点名称为person的所有节点,返回节点集合
        NodeList person = parse.getElementsByTagName("person");
        ArrayList<Person> personArrayList = new ArrayList<>();
        Person p=null;
        //此循环会迭代两次
        for (int i = 0; i < person.getLength(); i++) {
            Node item = person.item(i);
            p=new Person();
            //获取节点的属性值
            String personid = item.getAttributes().getNamedItem("personid").getNodeValue();
            p.setPersonid(personid);
            //获取当前节点的所有子节点
            NodeList childNodes = item.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
                Node item1 = childNodes.item(j);
                String nodeName = item1.getNodeName();
                if("name".equals(nodeName)){
                    p.setName(item1.getFirstChild().getNodeValue());
                }else if("address".equals(nodeName)){
                    p.setAddress(item1.getFirstChild().getNodeValue());
                }else if("tel".equals(nodeName)){
                    p.setTel(item1.getFirstChild().getNodeValue());
                }
                else if("fax".equals(nodeName)){
                    p.setFax(item1.getFirstChild().getNodeValue());
                }
                else if("email".equals(nodeName)){
                    p.setEmail(item1.getFirstChild().getNodeValue());
                }
            }
            personArrayList.add(p);
        }
        System.out.println("结果");
        System.out.println(Arrays.toString(personArrayList.toArray()));
    }

/*JDOM解析xml,使用jdom的jar包
    1、与DOM类似,基于树形结构
    2、与DOM区别:第三方开源组件,实现使用Java的Collection接口,比DOM效率快
    * */
    @Test
    public void JDOMParseXML() throws IOException, JDOMException {
        //创建JDOM解析器
        SAXBuilder saxBuilder = new SAXBuilder();
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("xml/Person.xml");
        org.jdom2.Document build = saxBuilder.build(is);
        Element rootElement = build.getRootElement();
        List<Person> list=new ArrayList<>();
        Person person=null;
        List<Element> children=rootElement.getChildren();
        for(Element e:children){
            person=new Person();
            String personid = e.getAttributeValue("personid");
            person.setPersonid(personid);
            List<Element> children1 = e.getChildren();
            for(Element ec:children1){
                String name = ec.getName();
                if("name".equals(name)){
                    person.setName(ec.getText());
                }else if("address".equals(name)){
                    person.setAddress(ec.getText());
                }else if("tel".equals(name)){
                    person.setTel(ec.getText());
                } else if("fax".equals(name)){
                    person.setFax(ec.getText());
                } else if("email".equals(name)){
                    person.setEmail(ec.getText());
                }
            }
            list.add(person);
        }
        System.out.println(Arrays.toString(list.toArray()));

    }

3、DOM4J解析

/*
* DOM4J解析,使用dom4j的jar包
* 1、基于树形结构,第三方组件
* 2、解析速度快,效率更高,使用的Java中的迭代器实现数据读取,在web框架中使用较多(Hibernate)
* */
    @Test
    public void dom4jParseXML() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("xml/Person.xml");
        org.dom4j.Document read = saxReader.read(is);
        org.dom4j.Element rootElement = read.getRootElement();
        Iterator<org.dom4j.Element> iterator = rootElement.elementIterator();
        List<Person> list=new ArrayList<>();
        Person p=null;
        while (iterator.hasNext()){
            p=new Person();
            org.dom4j.Element element = iterator.next();
            p.setPersonid(element.attributeValue("personid"));
            Iterator<org.dom4j.Element> iterator1 = element.elementIterator();
            while (iterator1.hasNext()){
                org.dom4j.Element next = iterator1.next();
                String name = next.getName();
                if("name".equals(name)){
                    p.setName(next.getText());
                }else if("address".equals(name)){
                    p.setAddress(next.getText());
                }else if("tel".equals(name)){
                    p.setTel(next.getText());
                } else if("fax".equals(name)){
                    p.setFax(next.getText());
                } else if("email".equals(name)){
                    p.setEmail(next.getText());
                }
            }
            list.add(p);
        }
        System.out.println(Arrays.toString(list.toArray()));
    }

4、把对象转为XML文件写入

 /*把对象转为XML文件写入
    * */
    @Test
    public void xmlEnCoder() throws FileNotFoundException {
        BufferedOutputStream bufferedOutputStream =
                new BufferedOutputStream(new FileOutputStream("test.xml"));
        XMLEncoder xmlEncoder = new XMLEncoder(bufferedOutputStream);
        Person p=new Person();
        p.setPersonid("111");
        p.setAddress("beijing");
        p.setEmail("123456@com");
        p.setFax("4567");
        p.setTel("1234567890");
        p.setName("haha");
        xmlEncoder.writeObject(p);
        xmlEncoder.close();
    }

5、从XML文件中读取对象

 /*从XML文件中读取对象*/
    @Test
    public void xmlDeCorder() throws FileNotFoundException {
        BufferedInputStream bufferedInputStream =
                new BufferedInputStream(new FileInputStream("test.xml"));
        XMLDecoder xmlDecoder = new XMLDecoder(bufferedInputStream);
        Person p = (Person)xmlDecoder.readObject();
        System.out.println(p);
    }

6、XStream解析

 /*使用XStream组件实现XML的解析与生成,xstream和xpp3的jar包
 */
    @Test
    public void xStream(){
        Person p=new Person();
        p.setPersonid("111");
        p.setAddress("beijing");
        p.setEmail("123456@com");
        p.setFax("4567");
        p.setTel("1234567890");
        p.setName("haha");

        XStream xStream = new XStream(new XppDriver());
        String s = xStream.toXML(p);
        System.out.println(s);
        
        //解析XML
        Person person = (Person)xStream.fromXML(s);
        System.out.println(person);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值