Java集合总结

1.1 null对象不可以调用方法,会导致空指针异常NullPointerException

eg:String str = null;
str.equals("zs");

 1.2 创建LinkedList(双向链表)时,有first(指向第一个节点)和last(调用完add之后指向最后添加的节点),①先创建新节点,存储值和赋值prev指向(上一个last节点),②再把上一个last节点的next指向当前last节点

 prev element next

 1.3 Collection集合都可以用iterator来遍历数据,这也是toString和foreach的底层

1.3.0 集合包括Collection和Map(键值对);Collection(接口)集合包含List(接口)和Set(接口)集合

1.3.1 List集合的实现类有ArrayList(动态数组)和LinkedList(双向链表),使用方法是一样的,遍历方式包括for循环、foreach、iterator;

1.3.2 Set集合包括TreeSet(底层是TreeMap)和HashSet(HashMap),Set集合只能先删再添加,Set的遍历方式包括foreach、iterator;

1.3.3 Map集合包括TreeMap(红黑树)和HahsMap(动态数组+链表+红黑树),Map集合的Key只能先删除再添加,Value可以覆盖,Map的遍历方式只能通过①keySet()和②entrySet()方法转换为Set集合,再通过foreach、iterator来遍历输出;

1.3.4 对于TreeXXX来说,底层是红黑树,在add()时就会排序,所以如果要存储自定义对象,需要①实现自然排序(Comparable)或者②传递比较器(Comparator);

1.3.5 对于HashXXX来说,底层是Hash表(动态数组+链表)+红黑树,在put()时会按hash值存储,所以如果要存储自定义对象,需要对Key对象①重写hashCode()和②equals()方法;

2.异常的处理,分为运行时异常(可处理可不处理)和检查时异常(必须处理)

try:执行可能产生异常的代码
catch:捕获异常,并处理异常
finally:最终总会执行(除非JVM停止)
throw new :手动抛出异常
throws:声明异常

try{
    //可能出现异常的代码
}catch(异常种类 变量名){
    //异常的处理代码
    //如e.printStack()  e.getMessage()
}finally{
    //无论是否异常都会执行,可以释放资源等
}
public class TestException3 {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int result=0;
		try {
			System.out.println("请输入第一个数字");
			int num1=input.nextInt();//InputMismatchException
			System.out.println("请输入第二个数字");
			int num2=input.nextInt();
			result=num1/num2;//发生异常// ArethmicException
			//手动退出JVM
			//System.exit(0);
		}catch (Exception e) {//捕获 Exception:是所有异常的父类
			//处理
			//e.printStackTrace();
			System.out.println(e.getMessage());
		}finally {
			System.out.println("释放资源...");
		}
		System.out.println("结果是:"+result);
		System.out.println("程序结束了...");
	}
}
public void setAge(int age) {
		if(age>0&&age<=120) {
			this.age = age;
		}else {
			//抛出异常
			throw new RuntimeException("年龄不符合要求");
		}
	}

 编写自定义异常 需继承Exception或Exception的子类,代表特定问题。

public AgeException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

 3.常用类

3.1 装箱拆箱(JDK1.5之后自动装箱拆箱)

最大的作用是使得基本数据类型也可以作为对象进行一些行为,比如调用方法,作为对象参数,返回为对象

装箱
1.构造方法 new Integer()
2.静态方法 valueOf() (推荐用静态方法,因为静态方法省资源,不用创建对象)

拆箱
1.方法XXXvalue()
2.静态方法 parseXXX()

 3.2 Character(字符的包装类,也算工具类)

//isDigit 是否是数字
//isLetter 是否是字母
//isUpperCase 是否是大写字母
//isLowerCase 是否是小写字母
//isLetterOrDigit 是否是字母或者数字

 3.3 Obeject类

 是所有类的父类或者间接父类,包含了hashCode()、equals()、toString()等方法,构造方法 public Object(){}

== 和 equals() 的区别
1.==是关系运算符,equals()是方法
2.==如果是引用类型是判断内存地址,equals()也是比较内存地址
3.当equals()重写之后,可以判断内容是否相等

 重写equals方法

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

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.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;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //手动重写equals()方法,用来比较内容

    @Override
    public boolean equals(Object obj) {
        //判断内存地址是否相等
        if (this == obj) {
            return true;
        }

        //判断对象类型是否相等
        if (obj instanceof User) {
            User user = (User) obj;

            //判断内容是否相等
            if (this.getName().equals(user.getName())) {
                if (this.getAge() == user.getAge()) {
                    return true;
                }
            }
            return false;
        }

        return false;
    }
}

4. String、StringBuffer、StringBuilder

1.String 是不可变的字符序列
2.StringBuffer(线程安全)和StringBuilder(线程不安全)是可变的字符序列

String常用方法:
    charAt(int index)返回 char指定索引处的值。
    
    String concat(String str)将指定的字符串连接到该字符串的末尾。
    
    boolean contains(CharSequence s)当且仅当此字符串包含指定的char值序列时才返回true。boolean equals(Object anObject)将此字符串与指定对象进行比较。
    
    byte[] getBytes()使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。
    
    int indexOf(int ch)返回指定字符第一次出现的字符串内的索引。
   
    boolean isEmpty()返回 true如果,且仅当 length()为 0 。
     
    int length()返回此字符串的长度。
        System.out.println(str.length());//16

    String replace(char oldChar, char newChar)返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar 。
     
    String[] split(String regex)将此字符串分割为给定的 regular expression的匹配。
        System.out.println(Arrays.toString(str.split("c")));//[ab, defghab, defghab, deab]

    String substring(int beginIndex)返回一个字符串,该字符串是此字符串的子字符串。
        System.out.println(str.substring(5));//fghabcdefghabcdeabc
      
    char[] toCharArray()将此字符串转换为新的字符数组。
        str = "AbCDefGh";
        System.out.println(Arrays.toString(str.toCharArray()));//[A, b, C, D, e, f, G, h]

    String toLowerCase()将所有在此字符 String使用默认语言环境的规则,以小写。
      

    String toUpperCase()将所有在此字符 String使用默认语言环境的规则大写。
    
    String trim()返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。
        str = "   abcd  ef g h    ";
        System.out.println(str.trim());//"abcd  ef g h"
StringBuilder的常用方法:
    末尾追加 append()
        
    capacity()    返回当前容量
       
    charAt(int index)     返回 char在指定索引在这个序列值
       
    delete(int start, int end)    删除此序列的子字符串中的字符。
      
    StringBuilder insert(int offset, int i)   将第二个 int参数的字符串表示插入到此序列中。

    reverse() 反转
       
    截取    --  从开始索引截取到末尾索引
    substring(int start, int end)
        System.out.println(sb.substring(2, 6));//[start,end)

5. Date类和SimpleDateFormat

1.new Date()            格林威治时间               
2.new Date(long date)   使用给定的毫秒时间值构造一个 Date对象。(要加时区小时时间,东八区+8小时)
public class Demo02 {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println("格林威治时间:" + date);//格林威治时间   Tue Nov 09 20:00:24 CST 2021

        //2021-11-09 20:00:00
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //调用方法格式化时间
        String timeStr = sdf.format(date);
        System.out.println("格式化时间:" + timeStr);

        //在1970年1月1日 00:00:00的基准时间上添加一个小时
        Date date1 = new Date(1000 * 60 * 60);
        String time1 = sdf.format(date1);
        System.out.println(time1);//东八区,+8小时
    }
}

6. BigInteger和BigDecimal

BigInteger:大长度的 int 类型包装类
BigDecimal:精准运算的类,可小数运算,可大数运算

7. System

Syste.exit() 退出JVM,0表示正常退出,非0表示非正常退出
System.gc() 运行垃圾回收器

8. 内部类

1.成员内部类(一般新建外部类,再通过外部类新建内部类)
2.局部内部类(不可以有访问修饰符,只能在方法内使用,在内部类外面创建对象)
3.静态内部类(在外部通过外部类.内部类创建,类型为内部类,常用于底层代码,在底层代码中,有时用来作为对象类比如Node<E>)
4.匿名内部类(适用于创建之后只使用一次或者少次的情况)

public class Demo01 {
    public static void main(String[] args) {
        //静态内部类,通过外部类直接调用,但是内部类还是要new
        //Inner inner = Outer.new Inner();
        Outer.Inner inner = new Outer.Inner();
        inner.setId(10);
        System.out.println(inner.getId());
    }
}
public class Demo01 {
    public static void main(String[] args) {
        //匿名内部类,适用于创建之后使用一次或者少次的情况
        MyInterfaceImpl mii = new MyInterfaceImpl();
        mii.method();

        System.out.println("------多态---------");
        MyInterface mi = new MyInterfaceImpl();
        mi.method();

        System.out.println("-------匿名内部类-------");
        MyInterface mi2 = new MyInterface() {
            @Override
            public void method() {
                System.out.println("通过匿名内部类的方式实现了接口的method方法");
            }
        };

        mi2.method();
    }
}

9. Collection集合(是接口)

传入的参数都要是对象,因为基本数据类型有装箱类(自动装箱),所以万物皆对象

9.1 List集合(是接口),有序可重复

1.ArrayList:底层是动态数组,初始化长度为0,当第一次添加时将长度改为10,每次要扩容1.5倍
LinkedList:底层是双向链表,first指向第一个节点,last指向已存储的最后一个节点,理论长度无限长
Vector:元老级,底层是动态数组,线程安全的集合,遍历方式和iterator有点相似

ArrayList和LinkedList方法相同,因为都实现了List类,
    只不过底层不一样,常用方法有:
        //添加    boolean     add(Object o)
        //修改    E           set(int index, E element)
        //删除    boolean     remove(@Nullable Object o)
        //查找    E           get(int index)
        //迭代器  Iterator<E> iterator()  

ArrayList 和 LinkedList的异同

1.ArrayList 底层是动态数组,LinkedList 底层是双向链表 2.ArrayList 查询比 LinkedList 更快
3.如果不需要扩容,ArrayList 末尾追加比 LinkedList 更快
4.修改对象 ArrayList 比 LinkedList 更快
5.中间插入和中间删除不同情况效率不一致
6.ArrayList 长度有限,LinkedList 理论上长度无限

 

 

 Vector类(很少用,但是实现了和ArrayList一样(存疑)的方法)

import java.util.Enumeration;
import java.util.Vector;

public class Demo02 {
    public static void main(String[] args) {
        //Vector
        Vector vector = new Vector();
        //
        vector.addElement("a");
        vector.addElement("b");
        vector.addElement("c");

        //Enumeration<E> elements()     返回此向量的组件的枚举。
        //相当于Vector的迭代器
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()) {
            System.out.println(elements.nextElement());
        }
    }
}

9.2 栈(类)和队列(接口,实现类是LinkedList)

栈和队列都是List的子类,所以也都能使用父类的方法,比如iterator()

 Stack:栈,用完即删,后进先出(LIFO)
Queue:队列,用完即删,先进先出(FIFO)

Stack和Queue的常用方法:
                            Stack           Queue
    特点                   后进先出         先进先出
    类型                     类              接口
    底层                    动态数组        双向链表
    存储                  add()/push()       add()
    取栈顶/队首元素         peek()           peek()
    用删栈顶/队首元素       pop()            poll()
    是否为空                        isEmpty()         
    容量                    size()           size()
    (迭代器)         Collection集合都可以用,隐式存在输出中

9.3 迭代器 iterator 调用方法

Iterator<E> iterator() 以正确的顺序返回该列表中的元素的迭代器。
调用.iterator()方法,返回一个迭代器,通过while(.hasNext())和.next()循环打印数据

//iterator()
    Iterator it = ll.iterator();
    System.out.println("迭代器iterator遍历方式:");
    //hasNext()     next()
    while (it.hasNext()) {
        System.out.println(it.next());
    }

 9.4 Set集合(是接口),无序不可重复

 1.TreeSet:无序可排序,不可重复(有比较才不重复),不能存储null
要实现“不可重复”,底层调用了TreeMap的put()方法,需要①实现自然排序或者②传递比较器

 2.HashSet:无序不可重复,可以存储null,在索引为0的位置(不一定是开头)
要实现“不可重复”,底层调用了HashMap的put()方法,需要重写hashCode()方法和equals()方法

自然排序:
        存储进 TreeSet 集合的对象类必须实现 Comparable 接口,重写 compareTo(),
        在 compareTo()里制定排序规则,返回正数存储的对象往右子树方向,
        返回负数存储的对象往左子树方向,返回0则不存储

    比较器:
        在创建 TreeSet 集合对象的时候,传递 Comparator 接口的实现类对象,
        重写 Comparator 接口的 compare() ,在 compare() 里制定排序规则


    自然排序 vs 比较器
        1.使用自然排序需要改变存储对象类的结构
        2.使用比较器会额外添加多一个类
        3.当比较器与自然排序共存的时候,使用比较器进行排序
public class Demo01 {
    public static void main(String[] args) {
        TreeSet<User> set = new TreeSet<>(new Comparator<User>() {
            //以 age 从小到大排序,如果 age 相同以 id 从大到小排序
            @Override
            public int compare(User user1, User user2) {
                if(user1.getAge() != user2.getAge()){
                    return user1.getAge() - user2.getAge();
                }
                return user2.getId() - user1.getId();
            }
        });
        set.add(new User(1,"zs",18));
        set.add(new User(6,"ls",20));
        set.add(new User(3,"ww",16));
        set.add(new User(2,"z6",18));
        set.add(new User(5,"t7",39));
        set.add(new User(4,"w8",18));
        set.forEach(item -> System.out.println(item));
    }
}

 

10. Map接口(k-v 键值对)

10.1 TreeMap 无序可排序

对key进行排序,key不可重复;value可以重复,可以为null

 存储自定义对象时,要①实现自然排序(Comparable)或者②传递比较器(Comparator)

public class Demo02 {
    public static void main(String[] args) {
        TreeMap<User, String> map = new TreeMap<>(new Comparator<User>() {
            @Override
            public int compare(User user1, User user2) {
                return user2.getId() - user1.getId();
            }
        });
        map.put(new User(1),"zs");
        map.put(new User(3),"ls");
        map.put(new User(2),"ww");
        map.put(new User(1),"zs");
        //按照id从大到小排序
        System.out.println(map);
        //两种遍历的方式
        //1.keySet
        Set<User> set1 = map.keySet();
        Iterator<User> it1 = set1.iterator();
        while (it1.hasNext()){
            System.out.println(it1.next());
        }

        //2.EntrySet
        Set<Map.Entry<User, String>> set2 = map.entrySet();
        Iterator<Map.Entry<User, String>> it2 = set2.iterator();
        while (it2.hasNext()){
            Map.Entry<User, String> entry = it2.next();
            User key = entry.getKey();
            String value = entry.getValue();
            System.out.println("Key:"+key+"Value:"+value);
        }
    }
}

 10.2 HashMap

底层是hash表(动态数组+链表)+红黑树,无序,key不可重复,value可以重复

 存储自定义对象时,要重写Key对象的①hashCode()和equals()方法

public class Demo02 {
    public static void main(String[] args) {
        HashMap<Object, Object> map = new HashMap<>();
        map.put(new Person(1),new User(1));
        map.put(new Person(2),new User(2));
        map.put(new Person(1),new User(2));
        map.put(new Person(2),new User(1));
        map.put(new Person(1),new User(1));
        System.out.println(map);
    }
}
public class Person {
    private int id;

    public Person(int id) {
        this.id = id;
    }

    public Person() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                '}';
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值