Java类集框架

2019-03-28  本文已影响0人  教堂白鸽

学习集合之前复习相关知识:

  • Hash:翻译为散列、哈希,所以散列和哈希指的是同一个概念。

  • 散列码:一种标识码,由散列码算法确定。

“散列码”就是用来把一堆对象散到各自的队列里去的一种标识码。

举个形象一点的例子,一年有 365 天,从 1 编号到 365,下面我定义一种编码方法,每个人按照他生日那天的编号作为他的标识码,这样,一群人每个人就会有一个标识码。

这个标识码有什么用呢?好,下面我说,请所有单号的人站到一起,所有双号的人站在一起。此后,当我要找一个人的时候,如果知道他的编号是单号,那我只需要到前面一堆人里去找,查找效率提高了一倍。

如果我说,请编号能被 16 整除的人站到一起,被 16 除余 1 的人站到一起,被 16 除余 2 的人站到一起…… 此后,当我要找一个人的时候,查找效率就会提高到 16 倍。

这就是散列码。所以,一个好的散列码算法,配合一个适当的存储机制,就能够实现高效的存储管理。

那么,不好的散列码算法会有多糟糕呢?比如,hashCode() 返回一个常量,那么,无论什么存储机制都会退化,所有的人都站在一堆里,查找效率无法提高。不过,也就只是影响效率,不会影响“正确性”,因为散列码的本性决定了,所有的算法都不应该假设两个不同的对象必须有不同的散列码。

  • 哈希表(也叫散列表):
    • 结合了数组和链表的优势,其实就是一种特殊的数据结构
    • 哈希表有多种不同的实现方法

看一下Object类中定义的方法

Object中的方法
  • toString()方法:

    • 返回对象的字符串表示形式,可以自己书写返回的格式(类型是字符串)
  • equals()方法和双等号:

    • equals:进行值的比较
    • ==:进行值和引用对象的地址是否一致
  • hashCode()方法:

    • 返回对象的哈希码值
  •    /**
       *This method is supported for the benefit of hash tables such as those *provided by java.util.HashMap
       *支持此方法是为了哈希表的优势,例如由HahMap提供的哈希表
       **/
    
  • Java中HashCode()方法就是根据一定的规则将于对象相关的信息(比如对象的存储地址、对象的字段等)映射成一个值,这个数值就是哈希码值(也叫散列码值)

一、类集

1、集合的作用

2、操作单值对象的集合-Collection家装

Collection家族

3、操作二元偶对象的集合-Map家族

Map家族

二、Collection接口

1553735515843.png

1、Collection有两大子接口

三、List接口

image.png

1、常用的实现类

  • ArrayList:①可调整大小的数组的实现②非线程安全③采用异步处理,性能更优
  • Vector:①用法与ArrayList相似②线程安全③采用同步处理方式,性能较低
  • LinkedList:实现链表结构,即实现了List接口又实现了Queue接口
(1)、ArrayList
package com.alexanderbai.collection.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * @Author AlexanderBai
 * @data 2019/3/26 17:00
 */
class Person implements Comparable<Person>{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public boolean equals(Object o) {//覆写equals方法
        if (this == o){ //判断地址是否相等
            return true;
        }
        if (!(o instanceof Person)) {//判断是否属于同一类对象
            return false;
        }
        /*上面的代码等价于
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        */
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&//依次进行属性比较
                Objects.equals(age, person.age);
       /*上面的代码等价于
        if (this.name.equals(person.name) && this.age == person.age) {
            return true;
        } else {
            return false;
        }
        */
    }
    @Override
    public int hashCode() {//覆写hashCode()的方法
        return this.name.hashCode() * this.age;//计算公式
    }
    @Override
    public String toString() {
        return "姓名:"+this.name +";年龄:"+this.age;
    }
    @Override
    public int compareTo(Person person) {//覆写comparTo()方法,指定排序规则
        if (this.age>person.age) {
            return 1;
        }
        if (this.age < person.age) {
            return -1;
        }
        return this.name.compareTo(person.name); //增加字符串的比较
    }
}

public class TestList {
    public static void main(String[] args) {
        List<String> listString = new ArrayList<>();
        //1、添加类库元素
        listString.add("Hello");
        listString.add("World!!");
        System.out.println("listString = " + listString);
        listString.remove("hello");
        System.out.println("listString = " + listString);

        //2、添加自定义元素
        List<Person> personList = new ArrayList<>();
        personList.add(new Person());
        personList.add(new Person("AlexanderBai",20));
        personList.add(new Person("Alexander",21));

        System.out.println("personList = " + personList);
        System.out.println("-------------------------------------------------------");
        personList.remove(new Person());
        //3、输出
        //第一种输出,集合的标准输出
        Iterator<Person> iterator=personList.iterator();
        while (iterator.hasNext()) {
            Person person=iterator.next();
            System.out.println(person.toString());
        }
        
        System.out.println("-------------------------------------------------------");
        //forEach输出
        for (Person person: personList) {
            System.out.println(person.toString());

        }

        System.out.println("-------------------------------------------------------");
        //简单佛如循环
        for (int i = 0; i <(personList.size()); i++) {
            System.out.println("personList.get("+i+") = " + personList.get(i));

        }
    }
}
(2)、Vector
public class TestList {
    public static void main(String[] args) {
        List<String> list= new Vector<>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        Iterator<String> iterator=list.iterator();
        while (iterator.hasNext()) {
            String string = iterator.next();
            System.out.println(string);
        }
    }
}
(3)、LinkedList
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
add() addAll(Collection<? extends E) addAll(int ,Collection<? extends E)
addFirst()/addLast() get() remove()/removeFirst()/removeLast()
pop()/push() peek() poll()/pollFirst()/pollLast()
package com.alexanderbai.collection.list;

import java.util.*;

/**
 * @Author AlexanderBai
 * @data 2019/3/26 17:00
 */
class Person implements Comparable<Person>{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public boolean equals(Object o) {//覆写equals方法
        if (this == o){ //判断地址是否相等
            return true;
        }
        if (!(o instanceof Person)) {//判断是否属于同一类对象
            return false;
        }
        /*上面的代码等价于
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        */
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&//依次进行属性比较
                Objects.equals(age, person.age);
       /*上面的代码等价于
        if (this.name.equals(person.name) && this.age == person.age) {
            return true;
        } else {
            return false;
        }
        */
    }
    @Override
    public int hashCode() {//覆写hashCode()的方法
        return this.name.hashCode() * this.age;//计算公式
    }
    @Override
    public String toString() {
        return "姓名:"+this.name +";年龄:"+this.age;
    }
    @Override
    public int compareTo(Person person) {//覆写comparTo()方法,指定排序规则
        if (this.age>person.age) {
            return 1;
        }
        if (this.age < person.age) {
            return -1;
        }
        return this.name.compareTo(person.name); //增加字符串的比较
    }
}

public class TestList {
    public static void main(String[] args) {
        List<Person> linkedList = new LinkedList<>();
        linkedList.add(new Person());
        linkedList.add(new Person("张三", 21));
        linkedList.add(new Person("李四", 22));
        linkedList.add(new Person("王五", 20));
        linkedList.add(new Person("赵六", 19));

        System.out.println("linkedList.get(2) = " + linkedList.get(2));
        System.out.println("((LinkedList<Person>) linkedList).peek() = " + ((LinkedList<Person>) linkedList).peek());//Retrieves(取出), but does not remove, the head (first element) of this list.
        System.out.println(linkedList);
        
        System.out.println("((LinkedList<Person>) linkedList).getFirst() = " + ((LinkedList<Person>) linkedList).getFirst());
        System.out.println("((LinkedList<Person>) linkedList).getFirst() = " + ((LinkedList<Person>) linkedList).getFirst());
        System.out.println("((LinkedList<Person>) linkedList).peekFirst() = " + ((LinkedList<Person>) linkedList).peekFirst());
        System.out.println(linkedList);
        
        ((LinkedList<Person>) linkedList).addFirst(new Person("新来的", 22));
        System.out.println(linkedList);
        System.out.println("((LinkedList<Person>) linkedList).peekLast() = " + ((LinkedList<Person>) linkedList).peekLast());
        
        Iterator<Person> iterator=linkedList.iterator();
        System.out.println("以先进先出的方式输出:");
        while (iterator.hasNext()) {
            Person person = iterator.next();
            System.out.println(person.toString());
        }
    }
}

四、Set接口

image.png

1、常用的实现类

  • HashSet:
    • 底层数据结构是哈希表(是一个元素为链表的数组)+红黑树
    • 实际上是封装了HashMap
    • 元素无序,允许为null
  • TreeSet

    • 底层数据结构实际上是一个TreeMap的实例(红黑树)
    • 可以实现排序功能
    • 元素不能为空
  • LinkedHashSet
    • 底层数据结构实际上是一个哈希表(是一个元素为链表的数组)+双向链表
    • 实际上是LinkHashMap
    • 允许元素为空

五、SortedSet接口

1、认识Sorted接口

2、指定年龄和姓名同时进行比较

3、指定年龄进行比较

4、指定姓名进行比较

六、集合的输出

1、Iterator迭代输出

Iterator只能进行单向的遍历,调用iterator()方法是注意类型转换

Iterator<String> iterator=list.iterator();

2、双向迭代输出


public class TestList {
    public static void main(String[] args) {
        List<String> list= new Vector<>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        ListIterator<String> listIterator=list.listIterator();
        System.out.println("由前向后输出:");
        while (listIterator.hasNext()) {
            String string = listIterator.next();
            System.out.println(string);

        }
        System.out.println("由后往前输出:");
        while (listIterator.hasPrevious()) {
            String string = ((ListIterator<String>) listIterator).previous();
            System.out.println(string);
        }
    }
}

3、foreach输出

集合也支持foreach和简单for循环的输出(见List接口的实现类ArrayList的输出操作)

七、Map接口

1553735515843.png

1、Map常用的实现类

(1)、HashMap
通过key获取value值:map.get(2) = xiaobai
以set集合的方式返回map集合:[1=AlexanderBai, 2=xiaobai, 3=dalao]
判断是否含有指定的key:key=3,value=dalao
判断是否含有指定的value值:搜索的value不存在
以set的方式返回所有的key,并输出全部的key
1、2、3、
以Collection的方式返回value,并输出全部的value
AlexanderBai、xiaobai、dalao、
输出map集合:
key=1,value=AlexanderBai
key=2,value=xiaobai
key=3,value=dalao
(2)、TreeMap
(3)、LinkedHashMap
public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
(4)、ConcurrentHashMap
public class TestMap {
    public static void main(String[] args) {
        Map<Integer, String> map = new ConcurrentHashMap<>();
        map.put(1, "c");
        map.put(2, "b");
        map.put(3, "a");

        map.put(6, "boss");
        map.put(5, "xiaobai");
        map.put(4, "AlexanderBai");

        System.out.print("通过key获取value值:");
        System.out.println("map.get(2) = " + map.get(2));

        System.out.print("以set集合的方式返回map集合:");
        System.out.println(map.entrySet());

        System.out.print("判断是否含有指定的key:");
        if (map.containsKey(3)) {
            System.out.println("key=3,value=" + map.get(3));
        } else {
            System.out.println("搜索的key不存在");
        }

        System.out.print("判断是否含有指定的value值:");
        if (map.containsValue("boss")) {
            System.out.println("搜索的value存在");
        } else {
            System.out.println("搜索的value不存在");
        }

        System.out.println("以set的方式返回所有的key,并输出全部的key");
        Set<Integer> keys=map.keySet();
        Iterator<Integer> integerIterator=keys.iterator();
        while (integerIterator.hasNext()) {
            System.out.print(integerIterator.next()+"、");
        }

        System.out.println();

        System.out.println("以Collection的方式返回value,并输出全部的value");
        Collection<String> values=map.values();
        Iterator<String> iterator=values.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next()+"、");
        }

        System.out.println();

        System.out.println("输出map集合:");
        Set<Integer> keys1=map.keySet();
        Iterator<Integer> integerIterator1=keys.iterator();
        while (integerIterator1.hasNext()) {
            Integer integer=integerIterator1.next();
            System.out.println("key="+integer+",value="+map.get(integer));
        }
    }
}

八、SortedMap接口

public interface SortedMap<K,V> extends Map<K,V>
public class TreeMap<K,V>
    extends AbstractMap<K,V>
      implements NavigableMap<K,V>, Cloneable, java.io.Serializable
public interface NavigableMap<K,V> extends SortedMap<K,V>

九、其他集合类

数组ArrayList 链表LinkedList
Stack 队列Queue

1、Stack类

1553678079937.png 1553593363380.png
package com.alexanderbai.collection.set;

import java.util.Stack;

/**
* @Author AlexanderBai
* @data 2019/3/27 17:17
*/
public class TestStack {
   public static void main(String[] args) {
       Stack<String> stringStack=new Stack<>();
       stringStack.add("B");
       stringStack.add("f");
       stringStack.add("A");
       stringStack.add("c");
       stringStack.add("b");
       System.out.println("stringStack.empty() = " + stringStack.empty());
       System.out.println("stringStack = " + stringStack);
       System.out.println("stringStack.peek() = " + stringStack.peek());
       System.out.println("stringStack = " + stringStack);
       System.out.println("stringStack.pop() = " + stringStack.pop());
       System.out.println("stringStack = " + stringStack);
       System.out.println("stringStack.lastElement() = " + stringStack.lastElement());
       System.out.print("新增元素:");
       stringStack.addElement("AlexanderBai");
       System.out.println("stringStack = " + stringStack);
       System.out.println("stringStack.contains(\"Alexander\") = " + stringStack.contains("Alexander"));
       System.out.print("清空栈");
       stringStack.removeAllElements();
       System.out.println("stringStack = " + stringStack);
   }
}
  • 运行结果:
stringStack.empty() = false
stringStack = [B, f, A, c, b]
stringStack.peek() = b
stringStack = [B, f, A, c, b]
stringStack.pop() = b
stringStack = [B, f, A, c]
stringStack.lastElement() = c
新增元素:stringStack = [B, f, A, c, AlexanderBai]
stringStack.contains("Alexander") = false
清空栈stringStack = []

2、Queue类

public interface Queue<E> extends Collection<E> 
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

3、属性类Properties

1553523496210.png
(1)、获取JVM属性
package com.alexanderbai.collection;

import java.util.Properties;

/**
 * @Author AlexanderBai
 * @data 2019/3/25 21:51
 */
public class PropertiesFileReadTest {
    public static void main(String[] args) {
        Properties properties=System.getProperties();
        properties.list(System.out);
    }
}

getProperties()方法说明:

1553525110065.png

list的说明:将属性以指定流的形式打印(上面是在控制台打印)


1553524723452.png
(2)、读取任意的配置文件
package com.alexanderbai.collection;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

/**
 * 读取和类在同一包下的属性文件
 * @Author AlexanderBai
 * @data 2019/3/25 21:51
 */
public class PropertiesFileReadTest {
    public static void main(String[] args) {
        Properties properties = new Properties();
        InputStream inputStream=null;
        //此方法配置文件和类必须再同一包想 
     inputStream=PropertiesFileReadTest.class.getResourceAsStream("test.properties"); 
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Enumeration propertyNames=properties.propertyNames();
        while (propertyNames.hasMoreElements()) {
            String key= (String) propertyNames.nextElement();
            String value=properties.getProperty(key);
            System.out.println( key +"="+value);
        }
    }
}
(3)、读取有关jdbc的配置属性
  • 下面两个文件都在com.alexanderbai.dbutil包下
  • dbConfig.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/scott
userName=root
password=ROOT
  • DBConnectionUtil.java
package com.alexanderbai.dbutil;

import java.io.IOException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
* @Author AlexanderBai
* @data 2019/3/26 0:07
*/
public class DBConnectionUtil {

public  Connection openConnection() {
Properties properties = new Properties();
String driver = null;
String url = null;
String userName = null;
String password = null;
try {
 properties.load(
         this.getClass().getResourceAsStream("dbConfig.properties")
 );
} catch (IOException e) {
 e.printStackTrace();
}
driver = properties.getProperty("driver");
url = properties.getProperty("url");
userName= properties.getProperty("userName");
password= properties.getProperty("password");

try {
 Class.forName(driver);
 return DriverManager.getConnection(url, userName, password);
} catch (SQLException e) {
 e.printStackTrace();
} catch (ClassNotFoundException e) {
 e.printStackTrace();
}
return null;
}

public static void main(String[] args) {
DBConnectionUtil dbConnectionUtil = new DBConnectionUtil();
System.out.println("dbConnectionUtil.openConnection() = " + dbConnectionUtil.openConnection());
  }
}

十、后言

以上只是java中集合框架的最基础部分,随着学习的深入,应该进一步学习java集合框架的源码实现,只有弄明白源码,才能真正领悟java类集的联系与区别。*

十一、Demo

1、一对多关系

2、多对多关系

上一篇 下一篇

猜你喜欢

热点阅读