Java进阶(一)

容器(Collection)

数组就是一种容器,可以在其中放置对象或基本类型数据。

优势:是一种简单的线性序列,可以快速地访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。

劣势:不灵活。容量需要事先定义好,不能随着需求的变化而扩容。

泛型(类似C++中的模板)

​ 就是“数据类型的参数化”。可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在嗲用泛型时必须传入实际类型。

package cn.Tony.Package;

public class TestGeneric {
    public static void main(String[] args) {
        Mycollection<String> mc = new Mycollection<String>();//实际参数

        mc.set("yhq",0);
        //mc.set(8888,1);
        //Integer a = (Integer)mc.get(1);
        String b = (String)mc.get(0);
        
        AddNumber<Integer> addNumber = new AddNumber();
        addNumber.addnum(10,20);
        System.out.println(addNumber.addnum(10,20));

    }
}
class Mycollection<E>{//E为通用数据类型,相当于形式参数,可以写多个
    Object[] objs = new Object[5];
    public void set(E obj,int index){
        objs[index] = obj;
    }
    public E get(int index){
        return (E)objs[index];
    }
}
class AddNumber<E>{
    public E addnum(Integer num1,Integer num2){
        return (E)num1;
    }
}
Collection接口

Collection是一个容器,是各种数据结构的泛型。

 public static void test01(){
        Collection<String> c = new ArrayList<>();
        System.out.println(c.size());

        System.out.println(c.contains("尼"));

        c.add("WDNMD");
        c.add("PDD");

        c.clear();
        c.remove("PDD");//将容器中对象的地址移除,实际的对象还是存在的
        System.out.println(c);
    }
    public static void test02(){
        List<String> list01 = new ArrayList<>();
        list01.add("aa");
        list01.add("bb");
        list01.add("cc");
        List<String>list02 = new ArrayList<>();
        list02.add("aa");
        list02.add("ee");
        list02.add("kk");
        list01.addAll(list02);
    }

ArrayList手动实现

package cn.lxk.mycollection;

import javax.management.RuntimeErrorException;
import java.util.Arrays;

public class YhqArrayList02<E> {
    private Object[] elementData;
    private int size;
    private static final int DEFALT_CAPACITY = 10;

    public YhqArrayList02() {
        elementData = new Object[DEFALT_CAPACITY];
    }
//数组初始化
    public YhqArrayList02(int capacity) {
        if (capacity<0){
            throw new RuntimeException("容器容量不能为负数");
        }else if (capacity==0){
            elementData = new Object[DEFALT_CAPACITY];
        }else {
            elementData = new Object[capacity];
        }
        elementData = new Object[capacity];
    }
//数组扩容
    public void add(E obj) {
        if (size==elementData.length){
            Object[] newArray = new Object[elementData.length+(elementData.length>>1)];
            System.arraycopy(elementData,0,newArray,0,elementData.length);
            elementData = newArray;//使得旧数组回收
        }
        elementData[size++] = obj;
    }
    public E get(int index){
        return (E) elementData[index];
    }
    public void set(E element,int index){
        checkRange(index);
        elementData[index] = element;
    }
//索引合法判断
    public void checkRange(int index){
        if (index<0||index>size-1){
            throw new RuntimeException("索引不合法");//抛出运行时异常
        }
    }
    public void remove(E element){
        for (int i = 0;i<size;i++){
            if (element.equals(get(i))){ //容器中所有的比较操作都是用equals

                //将该元素从中移除
                remove(i);
            }
        }
    }
//数组元素删除
    public void remove(int index){
        int numMoved = elementData.length-index-1;
        if (numMoved>0){
            System.arraycopy(elementData,index+1,elementData,index,numMoved);

        }
            elementData[--size] = null;
    }
    public int size(){
        return size;
    }
    public boolean isEmpty(){
        return size==0?true:false;
    }

    @Override
    public String toString() {
        return "YhqArrayList{" +
                "elementData=" + Arrays.toString(elementData) +
                ", size=" + size +
                '}';
    }

    public static void main(String[] args) {
        YhqArrayList02 s2 = new YhqArrayList02();
        for (int i = 0;i<40;i++){
            s2.add("Y"+i);
        }
        s2.set("YHQ",15);
        s2.remove(11);
        System.out.println(s2.toString());
        System.out.println(s2.get(10));

    }
}

LinkList手动实现

package cn.lxk.mycollection;

public class LinkList<E> {
    private Node first;
    private Node last;

    private int size;

    public void insert(int index,E element){
        Node node = new Node(element);
        Node temp = null;
        temp = getNode(index);
        node.previous = temp.previous;
        node.next = temp;
        temp.previous.next = node;
        temp.previous = node;

    }

    public void remove(int index){
        checkRange(index);
        Node temp = getNode(index);
        if (temp!=null){
            Node up = temp.previous;
            Node down = temp.next;
        if (up!=null){
            up.next = down;
        }
        if (down!=null){
            down.previous = up;
        }
        if (index==0){
            first = down;
        }
        if (index == size-1){
            last = up;
        }
        size--;
        }
    }
    public Node getNode(int index) {
        Node temp = null;
        if (index <= (size >> 1)) {
            temp = first;
            for (int i = 0; i < index; i++) {
                temp = temp.next;
            }
        } else {
            temp = last;
            for (int i = size - 1; i > index; i--) {
                temp = temp.previous;
            }
            return temp;
        }
        return temp;
    }

    public Object get(int index){
        checkRange(index);
        Node temp = getNode(index);

        return temp!=null?temp.element:null;
        }
    private void checkRange(int index){
        if (index<0||index>size-1){
            throw new RuntimeException("索引数字不合法"+index);
        }
    }

    public void add(E obj){
      Node node = new Node(obj);

      if (first==null){
          first = node;
          last = node;
      }else {
          node.previous = last;
          node.next = null;

          last.next = node;
          last = node;
      }
      size++;

    }
    public String toString(){
        StringBuilder sb = new StringBuilder("[");
        Node temp = first;
        while (temp!=null){
            sb.append(temp.element+",");
          //  System.out.println(temp.element);
            temp=temp.next;
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
       }

    public static void main(String[] args) {
        LinkList<String> list = new LinkList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        list.add("f");

        System.out.println(list.toString());
        System.out.println(list.get(2));
        list.remove(0);
        list.insert(3,"yhq");
        System.out.println(list);
    }
}

Map接口

​ Map就是用来存储“健(key)-值(value)对”的。Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。

public class TestMap {
    public static void main(String[] args) {
        Map<String,Integer> m1 = new HashMap<>();
        m1.put("one",1);
        m1.put("tow",2);
        m1.put("three",3);
        m1.put("four",4);
        System.out.println(m1.get("one"));
    }
}

另外,Map中的value也可以为对象:

class Employee{
    private int id;
    private String ename;
    private double salary;

    public Employee(int id, String ename, double salary) {
        this.id = id;
        this.ename = ename;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", ename='" + ename + '\'' +
                ", salary=" + salary +
                '}';
    }
}
public class TestMap {
    public static void main(String[] args) {
      Employee e1 = new Employee(1001,"yhq",4000);
        Employee e2 = new Employee(1002,"lxk",5000);
        Employee e3 = new Employee(1003,"lxy",6000);
        Map<Integer,Employee> map = new HashMap<>();
        map.put(1001,e1);
        map.put(1002,e2);
        map.put(1003,e3);
        System.out.println(map);
    }

哈希表

HashMap底层实现采用了哈希表,这是一种非常重要的数据结构。哈希表的基本结构就是“数组+链表”。手动实现HashMap如下:

HashNode.java:

package cn.lxk.mycollection;

public class HashNode<K,V> {
    int hash;
    K key;
    V value;
    HashNode next;
}

HashMap.java:

package cn.lxk.mycollection;

import java.util.Arrays;

//自定义HashMap
public class HashMap<K,V> {
    HashNode[] table; //位桶数组
    int size;

    public HashMap(){
        table = new HashNode[16];
    }

    public void put(K key,V value){
        //还需要考虑数组扩容的问F题
        HashNode newNode = new HashNode();
        newNode.hash = myHash(key.hashCode(),table.length);
        System.out.println("Hash Code"+key.hashCode());
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        HashNode temp = table[newNode.hash];

        HashNode iterLast = null; //正在遍历的最后一个元素
        //若此处数组元素为空,则直接放新节点进去
        boolean keyRepeat = false;
        if (temp==null){
            table[newNode.hash] = newNode;
            size++;
        }else {
            //此处数组元素不为空,则遍历对应链表
            while (temp!=null){
                //判断key如果重复,则覆盖
                if (temp.key.equals(key)){
                    keyRepeat = true;
                    temp.value = value;//覆盖value即可,其他不变
                    System.out.println("key重复了");
                    break;
                }else {
                    //key不重复,则遍历下一个
                    iterLast = temp;
                    temp = temp.next;
                }
            }
            if (!keyRepeat){
                iterLast.next = newNode;
                size++;
            }
        }
    }
    public int myHash(int v,int length){
        System.out.println("哈希值:"+(v&(length -1)));
        return v&(length -1); //求余
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("{");
        //遍历bucket数组
        for (int i = 0;i<table.length;i++){
            HashNode temp = table[i];
            //遍历链表
            while (temp!=null){
                sb.append(temp.key+":"+temp.value+",");
                temp = temp.next;
            }

        }
        sb.setCharAt(sb.length()-1,'}');
        return sb.toString();
    }
    public V get(K key){
        int hash = myHash(key.hashCode(), table.length);
        V value = null;
        if (table[hash]!=null){
            HashNode temp = table[hash];
            while (temp!=null){
                if (temp.key.equals(key)){//如果相等,则说明找到了键值对,返回相应的value
                    value = (V)temp.value;
                    break;
                }else {
                    temp = temp.next;
                }
            }
        }

        return value;
    }

    public static void main(String[] args) {
        HashMap<Integer,String> m = new HashMap<>();
        m.put(10,"aa");
        m.put(53,"bb");//hash值是5
        m.put(12,"cc");
        m.put(13,"dd");
        m.put(69,"sssss");//hash值是5
        m.put(85,"yhq"); //hash值是5
        System.out.println(m.get(69));
    }
}

迭代器

迭代器是遍历collection的一种工具。

package cn.lxk.mycollection;

import java.util.*;
import java.util.HashMap;

public class TestIterator {
    public static void main(String[] args) {
        testIteratorMap();
    }
    public static void testIteratorList(){
        List<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        //使用迭代器遍历list,相当于提供一个专业的接口来遍历容器
        for (Iterator<String >iter = list.iterator();iter.hasNext();){
        //(获得迭代器;判断有没有下一个)
            String temp = iter.next(); //返回元素
            System.out.println(temp);
        }
    }
    public static void testIteratorMap(){
        Map<Integer,String>map1 = new HashMap<>();
        //第一种遍历Map的方式
        Set<Map.Entry<Integer,String>> ss = map1.entrySet();				 //Map.Entry<Integer,String>相当于一个键值对类型
        for (Iterator<Map.Entry<Integer,String>>iter = ss.iterator();iter.hasNext();){
            Map.Entry<Integer,String> temp = iter.next();
            System.out.println(temp.getKey()+"---"+temp.getValue());
        }
        //第二种遍历Map的方式
        Set<Integer> keySet = map1.keySet();
        for (Iterator<Integer>iter=keySet.iterator();iter.hasNext();){
            Integer key = iter.next();
            System.out.println(key+"----"+map1.get(key));
        }
    }
}

使用while来遍历:

Iterator iter = list.iterator();
while(iter.hasNext()){
	Object obj = iter.next();
	iter.remove();//按条件删除时,也建议使用此种方式
	
}
JavaBean

​ JavaBean 是一种JAVA语言写成的****可重用组件****。为写成JavaBean,类必须是****具体的和公共的*,并且具有****无参数的**构造器*。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,****set和get方法获取****。

public class TestStoreData {
    public static void main(String[] args) {
        User user1 = new User(1001,"张三",2000,"2018.9.10");
        List<User>list = new ArrayList<>();
        list.add(user1);
        for (User u:list){
            System.out.println(u);
        }
        Map<Integer,User>map = new HashMap<>();
        Set<Integer>keyset = map.keySet();
        map.put(1,user1);
        for (Integer key:keyset){
            System.out.println(key+"===="+map.get(key));
        }
    }
}
class User{
    private int id;
    private String name;
    private double salary;
    private String hiredate;

    public User(){//一个完整的javabean。要有set和get方法,以及无参构造器

    }

    public User(int id, String name, double salary, String hiredate) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.hiredate = hiredate;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getHiredate() {
        return hiredate;
    }

    public void setHiredate(String hiredate) {
        this.hiredate = hiredate;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                ", hiredate='" + hiredate + '\'' +
                '}';
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值