毕向东老师Java视频笔记-集合(未完)

集合框架图

List类:有序,可重复–>有一些Collection类没有的方法,因为有脚标
* ArrayList
* LinkedList
* Vector

Set类:无序(存入和取出的顺序不一致),不可重复–>和Collection的方法一致
* HashSet
* TreeSet

1 使用LinkedList模拟堆数据结构和栈数据结构的存取操作过程

class Que 
{
    private LinkedList link = new LinkedList();
    public void myAdd(Object obj){
        link.addFirst(obj);
    }
    public Object myGet(){
        return link.removeFirst();
    }
    public boolean isNull(){
        return link.isEmpty();
    }
    public static void main(String[] args) 
    {
        Que q = new Que();
        q.myAdd("java01");
        q.myAdd("java02");
        q.myAdd("java03");
        q.myAdd("java04");
        while(!q.isNull())
        {
            System.out.println(q.myGet());
        }
    }
}

2 集合类的遍历:

1 使用Iterator迭代器遍历:

实现过程:

ArryList al = new ArryList();
al.add(obj);
for(Iterator it = al.iterator();it.hasNext();){
    it.next();
}

底层实现,内部类

class ArrayList{
    //ArrayList集合中有多个对象,存放的是它们的引用o1,o2,o3;
    Object o1 = new Object():
    Object o2 = new Object():
    Object o3 = new Object():
        class Itr implements Iterator //内部类实现Iterator接口
        {
            hasNext();
            next();
            remove();//方法。。。
        }
        public Iterator iterator(){
            new Itr();
        }
}

注意在使用对象传递时的安全问题(存入集合中元素均视为Object类型,通常都有向上转型的操作):

import java.util.*;
class Person
{
    private String name;
    private int age;
    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public static void main(String[] args) 
    {
        ArrayList al = new ArrayList();
        al.add(new Person("张洪题",28));//ArrayList类的方法add()定义为:boolean add(Object obj),因此,这一步做的动作相当于Object obj = new Person();存在向上转型
        al.add(new Person("徐尚",27));
        al.add(new Person("蒋晨晨",25));

        Iterator i = al.iterator();

        while (i.hasNext())
        {
            Person p = (Person)i.next();//如果直接使用i.next().getName();其中i.next()指的是Object类的对象,而Object类是没有getName()方法的,要想使用Person类的方法,必须向下转型
            System.out.println(p.getName()+"---"+p.getAge()+"岁");
        }
    }
}

2 ListIterator

在Iterator遍历过程中,不能使用集合方法对元素进行增删操作,而Iterator只提供了hasNext(),next(),remove();三种方法,因此对于元素有脚标的ArryList集合,遍历时使用ListIterator迭代器;

3 在集合中存入实际对象

List集合,判断其中元素是否相同,使用的是equals()方法:
1. Object类的equals()方法:比较对象地址值;
2. String类的equals()方法:也是比较对象的地址值,因此对于String str1 = new String(“abc”)和String str2 = new String(“abc”),使用equals()方法将返回false;
3. 实际开发中,经常重写equals()方法(权限public):下面这个例子必须会写!
4. List集合中的contains();remove();方法底层都调用了equals();方法!!

import java.util.*;

class Person
{
    private String name;
    private int age;
    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    String getName(){
        return name;
    }
    int getAge(){
        return age;
    }
    //该equals方法,在e.contains(o)方法使用时才能被隐式调用!-->o==null?e==null : o.equals(e)
    public boolean equals(Object obj){//因为Object类中equals方法是public修饰,为了重写该方法,权限必须覆盖
        if (!(obj instanceof Person))
        {
            return false;//此处应该使用try catch抛出异常;
        }
        Person p = (Person)obj;//向下转型
        return name==p.getName() && age==p.getAge();
    }

}

class EqualsDemo 
{
    public static ArrayList singleElement(ArrayList al){
        //创建一个新的ArrayList集合用于存储单一元素
        ArrayList newAl = new ArrayList();
        Iterator i = al.iterator();
        while (i.hasNext())
        {
            Object obj = i.next();
            if(!newAl.contains(obj)){//contains方法,底层实现也是使用Object类的equals方法;
                newAl.add(obj);
            }
        }
        return newAl;
    }
    public static void main(String[] args) 
    {
        ArrayList al = new ArrayList();
        //其中放入相同的用户,要求剔除
        //思路:创建一个静态方法,用于比较ArrayList中存放的Object类的具体值是否相同,需要重写所存储对象所属类的equals方法;
        al.add(new Person("Zhang Hongti",28));
        al.add(new Person("Xu Shang",27));
        al.add(new Person("Jiang Chenchen",25));
        al.add(new Person("Xu Shang",27));

        al=singleElement(al);

        Iterator i = al.iterator();
        while(i.hasNext()){
            Person p = (Person)i.next();
            System.out.println(p.getName()+"---"+p.getAge());
        }
    }
}

4 HashSet

4.1 在HashSet中存入对象

  1. 不是按照你的存入顺序,而是按照对象的哈希值
  2. HashSet中存放对象引用的哈希值可以相同,这种情况下,会进一步比较是否属于同一个对象,从而确定要不要再集合中放入两个元素;
  3. 也就是说,判断是否在HashSet集合中加入一个不重复元素的步骤是:
    1. 调用hashCode()方法判断哈希值是否相同,不同则直接存入;
    2. 调用equals()方法继续判断,返回false则存入;
    3. **注意:**hashCode()和equals()方法常常需要被改写!不需要调用,使用集合Set类方法的时候从底层隐式调用的;
package com.cityu.collection;

class Demo{
    //重写Object类的hashCode()方法
    public int hashCode(Object obj){
        return 199;
    }
}
public class HashSet {
    public static void main(String[] agrs){
        Demo d1 = new Demo();
        Demo d2 = new Demo();
        System.out.println(d1);//底层调用Object类的toString()方法getClass().getName()+"@"+Integer.toHexString(hashCode());
        System.out.println(d2);
    }
}

5 TreeSet

  • 底层数据结构是二叉树,保证数据唯一性的依据是compareTo方法return 0;
    1. 可以通过让对象所属类实现Comparable接口改写compareTo方法实现特定的排序方式;
    2. 定义一个比较器
/*
 *在TreeSet集合中存入自定义对象,希望按照年龄进行排序
 * 
 * */
package com.cityu.collection;

import java.util.*;

public class TreeSetDemo {
    public static void main(String[] agrs){
        TreeSet ts = new TreeSet();

        ts.add(new Student("Zhang Hongti01", 23));
        ts.add(new Student("Zhang Hongti03", 19));
        ts.add(new Student("Zhang Hongti04", 19));//在主要条件相同的情况下,再去对比下一个条件,否则,会被当做相同元素无法存入集合
        ts.add(new Student("Zhang Hongti05", 40));//向TreeSet中存入的对象必须实现Comparable接口,也就是该对象必须可以进行自然排序

        for(Iterator i = ts.iterator();i.hasNext();){
            Student s = (Student)i.next();
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

class Student implements Comparable
{
    private String name;
    private int age;
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
    public int compareTo(Object obj){
        if(!(obj instanceof Student))
            throw new RuntimeException("Wrong Class!");
        Student str = (Student)obj;
        if(this.age>str.age)
            return 1;
        if(this.age==str.age){
            return this.name.compareTo(str.name);//字符串本身具有比较性,实现了Comparable接口
        }
        return -1;
    }
}

使用定义比较器的方式使用自定义方法排序,必须会写!

/*
 * 使用TreeSet集合对存入其中的字符串,按照其长度排序输出:
 * 使用两种方法:
 * 1. 让字符串对象实现Comparable接口,并重写compareTo()方法;
 * 2. 让TreeSet容器自身具备比较性:定义一个比较器,在构造容器时,初始化该比较器;
 * 对比着两种方法:常用的是使用比较器
 * */
package com.cityu.collection;

import java.util.*;

class SetCompare implements Comparator
{
    public int compare(Object o1,Object o2){
        String str1 = (String)o1;
        String str2 = (String)o2;
        int num = str1.length()-str2.length();
        if(num==0){
            return str1.compareTo(str2);
        }
        return num;
    }
}

public class TreeSetTest {
    public static void main(String[] agrs){
        TreeSet ts = new TreeSet(new SetCompare());

        ts.add("abcd");
        ts.add("abe");
        ts.add("abcdef");
        ts.add("efcd");
        ts.add("bfcd");

        for(Iterator i = ts.iterator();i.hasNext();){
            String string = (String)i.next();
            System.out.println(string);
        }
    }
}

6 Map集合

7. 集合框架的工具类

1. Collections类

2. Arrays类

  • 用于操作数组的工具类
  • asList()方法:
    • 将数组变成List:好处是可以使用集合的思想和方法来操纵数组
class ArrayDemo{
    public static void main(String[] agrs){
        String[] arr = {"abd","cdb","ddd"};
        List<String> list = Arrays.asList(arr);
        System.out.println("arr:"+arr);
        System.out.println("list:"+list);
        System.out.println("contains:abd?"+list.contains("abd"));
    }
}

输出:
arr:[Ljava.lang.String;@100363
list:[abd, cdb, ddd]
contains:abd?true

  • 将List变成数组:是为了限制进一步对元素的操作(增删);
  • 转换时,要确定数组大小:大了,补null;小了,创建新数组;最好是大小刚好:
ArrayList<String> al = new ArrayList<String>();
String[] arr = al.toArray(new String[al.size()]);

3. 迭代器接口(Iterable)

实现Iterable接口的类对象可以成为for-each循环的target:高等级for循环
for(数据类型 变量名:被遍历的集合(Collection)或者数组)

  • 对集合遍历,只能获取元素,不能修改
ArrayList<String> al = new ArrayList<String>();
al.add("abd");
al.add("add");
al.add("fgh");

for(String s:al){
    System.out.println(s);
}

for(String s:al){
    s = "aa";
}
System.out.println(s);

输出:
abd
add
fgh
[abd, add, fgh]

  • 因此,使用迭代器,可以使用remove元素的操作;
  • 如果使用ListIterator,还可以遍历过程中进行增删改查操作;

  • Map集合不能使用,使用keySet()或者entrySet()获得Map中键的Set集合或者键值映射关系Set集合;

HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1,"a");
hm.put(2,"b");
hm.put(3,"c");

Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
for(Map.Entry<Integer,String> me:entrySet){
    System.out.println(me.getKey()+":"+me.getValue());
}

//或者简写为:
for(Map.Entry<Integer,String> me:hm.entrySet()){
    System.out.println(me.getKey()+":"+me.getValue());
}

4. 可变参数

其实就是数组,不用每次都建立数组对象,只需要将要操作的元素作为参数即可,隐式地将这些元素封装成数组:

{   ...
    varPara(2,3,4,5);
    varPara(3,4,5,6,6,45)
    public static void varPara(int... arr){
        System.out.println(arr);
    }
}
  • 注意:可变参数一定要定义在参数列表的最后面,也就是说在可变参数后面不能继续定义参数

5. staticImport静态导入

对于全部都是静态方法的工具类
import static java.util.Arrays.*;

注意:如果方法重复(通常会和Object类的方法冲突)时,要明确所属类或者对象;

8 常见类:

1. System类:

没有构造函数,全是静态方法,一种工具类。
Properties类是HashTable子类,可以使用Map集合的方法;
System类的getProperties()静态方法,返回Properties子类;

import java.util.*;

public class SystemDemo {
    public static void main(String[] agrs){
        Properties prop = System.getProperties();
        Set<Object> keySet = prop.keySet();
        Iterator<Object> it = keySet.iterator();
        while(it.hasNext()){
            String value = (String)prop.get(it.next());
            System.out.println(value);
        }
        //由于Set集合实现了Iterable接口,因此可以使用for-each高级循环
        for(Object obj:prop.keySet()){
            String value = (String)prop.get(obj);
            System.out.println(value);
        }
    }
}

8.2 Runtime类

Runtime类同样没有构造函数,但是大多是非静态方法,如何调用?

  • 使用getRuntime()静态方法,返回Runtime本类对象,就可以获得对象,从而调用该类方法;(单例设计模式,程序中只存在一个对象)
  • Runtime类方法Process exec(String comand)
public class RuntimeDemo {
    public static void main(String[] agrs) throws Exception
    {
        //Runtime r = Runtime.getRuntime();
        //r.exec("C:\\Program Files\\Tencent\\QQ\\Bin\\QQ.exe");//因为“\”是转义字符
        //杀死本程序启动的进程:无法杀平台进程,因为虚拟机无法拿到平台进程的对象p
        Runtime r = Runtime.getRuntime();
        Process p = r.exec("C:\\Program Files\\Tencent\\QQ\\Bin\\QQ.exe");//因为“\”是转义字符
        Thread.sleep(4000);
        p.destroy();
    }
}

8.3 日期类Date

import java.text.*;//导包
class DateDemo{
    public static void main(String[] agrs){
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/mm/dd");//创建一个模式对象
        //使用该模式对象调用该类方法对日期对象格式化操作,返回字符串
        String mydate = sdf.format(d);
        System.out.println(mydate);
    }
}

Calender类:获取修改时间,日期等(可以自定义格式)
* 0代表一月

8.4 Math.Random

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值