从0基础开始学习Java第8天

最近一直被琐事耽误,学习java虽然没停,但是每天学的比较少,继续加油吧!
容器,用来装其他对象的对象。数组也是个容器,它作为容器的优势是简单,效率高,缺点是不灵活,容量不可变。
在这里插入图片描述
这里用一张图显示一下容易的结构吧。我学习也是按照这个来的。
基础阶段,不仅要学习使用,还要多练习,所以我还自己实现了这些容器,虽然没有很完美,但是作为练习,还是可以的。
学习容器之前,要知道泛型,可以帮助我们建立类型安全的集合,可以理解为容器的标签。本质是数据类型的参数化。理解为数据类型的占位符,常用T E V三者字母表示。


class MyCollection <E>{
 Object []objs=new Object[5];
 public void set(E  e,int index) {
  objs[index]=e;
 }
// public Object get(int index) {
//  return objs[index];
// }
 public E get(int index) {
  return (E) objs[index];
 }
}

定义一个类,使用表示一种数据类型。

MyCollection<String> mc=new MyCollection<>();//这里写String,返回的就是String
  mc.set("小明", 0);
  //mc.set(1234, 1);
  //Integer a=(Integer)mc.get(1);
  String b=mc.get(0);//无泛型,需要每次都强制类型转换
  String c=mc.get(0);//加泛型,无需强制转换,因为已经用String站位了
  System.out.println(c);

接下来测试Collection接口中的方法。
ArrayList实现类

Collection<String> c=new ArrayList<>();
  System.out.println(c.size());//返回容器中元素数量
  System.out.println(c.isEmpty());//看容器是否是空的
  c.add("小明");//泛型是String,所以这里也是字符串
  System.out.println(c.contains("小明"));//测试是否包含元素
  c.add("小红");
  System.out.println(c);
  System.out.println(c.size());//返回容器中元素数量
  c.remove("小红");//移除,不是删除,容器只是存放了地址,移除的只是地址,但是那个对象还在
  System.out.println(c);
  c.clear();//移除所有元素  
  System.out.println(c.size());
  
  Object []objs=c.toArray();//转出来一个数组
  System.out.println(objs);

其他的实现类的方法与ArrayList的方法基本类似,因为他们都是继承自Collection接口。

自己实现一个List

public class LMList5 <E>{
 private  Object[] elemantData;
 private int size;
 private static final int DEFALT_CAPACITY=10;//默认长度
 public  LMList5() {
  elemantData=new Object[DEFALT_CAPACITY];//默认长度为10
 }
 public  LMList5(int capacity) {//也可以设置长度
  if (capacity<0) {
   throw new RuntimeException("长度不能为负数");
  }
  else if (capacity==0) {
   elemantData=new Object[DEFALT_CAPACITY];//默认长度为10
  }
  else {
   elemantData=new Object[capacity];
  }
}

public void add(E element) {
  //什么时候扩容
  if (size==elemantData.length) {
   //怎么扩容?
   Object []newArray=new Object[elemantData.length+(elemantData.length>>1)];  //扩容一半的空间
   System.arraycopy(elemantData, 0, newArray, 0, elemantData.length);
   elemantData=newArray; 
  }
  elemantData[size++]=element; 
 }
public E get(int index) {
  //检查索引合法性[0,size)
  cheakRange(index);
  return (E)elemantData[index];
 }

public void set(int index,E element) {
  //检查索引合法性[0,size)
  cheakRange(index);
  elemantData[index]=element;
 }

//检查索引合法性函数
 public void cheakRange(int index) {
  //检查索引合法性[0,size)
  if (index<0||index>size-1) {
   throw new RuntimeException("索引不合法:"+index);
  }
 }
public void remove(int index) {
  cheakRange(index);
  int numMoved=elemantData.length-index-1;
  if (numMoved>0) {
   System.arraycopy(elemantData, index+1, elemantData, index,numMoved);
  }
   elemantData[--size]=null;
 }

//移除元素
 public void remove(E element) {
  //element将他挨个和所有元素比较,获得第一个比较为true的返回
  for(int i=0;i<size;i++) {
   if (element.equals(get(i))) {//容器中所有的比较操作都是用的equals
    remove(i);
   }
  }
 }

public int  size() {
  return size;
 }
 public boolean isEmpty() {
  if (size==0) {
   return true;
  }
  else {
   return false;
  }
 }

@Override
 public String toString() {
  StringBuilder sb=new StringBuilder();
  sb.append("[");
  for(int i=0;i<size;i++) {
   sb.append(elemantData[i]+",");
  }
  sb.setCharAt(sb.length()-1, ']');
  return sb.toString();
 }

public static void main(String[] args) {
  LMList5<String> lm1=new LMList5<>();
  for (int i = 0; i <40; i++) {
   lm1.add("小"+i);
  }
  lm1.add("aa");
  lm1.add("bb");
  lm1.add("cc");

System.out.println(lm1);
  System.out.println(lm1.get(40));
  //lm1.set(-50,"kk");
  lm1.remove(40);
  lm1.remove("bb");
  System.out.println(lm1);
  System.out.println(lm1.get(40));
  System.out.println(lm1.size());
  System.out.println(lm1.isEmpty());
 }
 }

这些东西还是练一下的比较好,并不是重复造车轮,而是练习。
然后还有自己练习的LinkList。LinkList实际上是用了节点连接所有的数据。所以首先定义一个节点类,这个类需要有上一个元素,本元素,下一个元素。

public class Node2<E> {
 Node2 <E>previous;
 E element;
 Node2 <E>next;
}

接下来是实现LinkList,这个代码是自己练习写的,不是跟着老师上课写的,注释好像没怎么写,不过比较简单。


public class TestLinkedList2 <E>{
int size=0;
Node2<E> lastNode=new Node2<>();
 Node2<E> fristNode=new Node2<>();

public void put(E element) {
  if (lastNode.element==null) {
   lastNode.previous=null;
   lastNode.element=element;
   lastNode.next=null; 
   fristNode=lastNode;
  }
  else {
   Node2 temp=new Node2();
   temp.previous=lastNode;
   temp.element=element;
   temp.next=null;
   lastNode.next=temp;
   lastNode=temp;
  }
  size++;
 }

public E get(int index) {
  Node2 <E>temp=new Node2<>();
  temp=fristNode;
  for (int i = 0; i < index; i++) {
   temp= temp.next;
  }
  return (E)temp.element;
 }

public void put(int index,E element) {
  Node2 <E>temp=new Node2<E>();
  temp=fristNode;
  for(int i=0;i<index;i++) {
   temp=temp.next;
  }
  Node2 <E>up=new Node2<E>();
  Node2 <E>newNode=new Node2<E>();
  up=temp.previous;
  up.next=newNode;
  newNode.previous=up;
  newNode.element=element;
  newNode.next=temp;
  temp.previous=newNode;
 }
 public void remove(int index) {
  Node2 <E>temp=new Node2<E>();
  temp=fristNode;
  for(int i=0;i<index;i++) {
   temp=temp.next;
  }
  Node2 <E>up=new Node2<E>();
  Node2 <E>down=new Node2<E>();
  up=temp.previous;
  down=temp.next;
  up.next=down;
  down.previous=up;
 }

@Override
 public String toString() {
  StringBuilder sb=new StringBuilder("[");
  Node2<E> temp=new Node2<E>();
  temp=fristNode;
  while (temp.next!=null) {
   sb.append(temp.element+",");
   temp=temp.next;
  }
  sb.append(temp.element+"]");
  return sb.toString();
 }
 public static void main(String[] args) {
  TestLinkedList2<String> t=new TestLinkedList2<>();
  t.put("aa");
  t.put("bb");
  t.put("cc");
  System.out.println(t);
  System.out.println(t.get(1));
  t.put(2,"dd");
  System.out.println(t);
  t.remove(2);
  System.out.println(t);
  }
}

这里实现了一下基本的函数,为了显示,把ToString()重写了一下。
写的时候,我会出一些错误,但是最近学习了调试程序,通过看每个值的逻辑变化,都把错误改过来了。
再来个map吧。其实这些东西没什么可以写的,知道怎么用,知道原理就行了,剩下的就是敲敲敲敲。。。
Map ,有一个键值对,<K,V>,不可重复,若重复,则替换,意思就是一个K对应一个V,如果给K不同的值,就会替代。
然后Hash表,就是一个数组,存放map的数组。然后节点有四个属性,hash值,Key,Value,Next。通过Key 的值获得Hash的值,方法是K&(length-1),length是数组的长度,使用这种方法,数组长度必须是2的整数次方。

public class Node2<K,V> {
 int hash;
 K key;
 V value;
 Node2 next;
}
public class TestMap4 <K,V>{
 Node2 []table;//位桶
 int size;//存放建值对
 public TestMap4() {
  table=new Node2[16];//必须是2的整数次方
 }

public void put(K key,V value) {
  //定义新节点对象
  Node2  newNode2=new Node2();
  newNode2.hash=myHash(key.hashCode(), table.length);
  newNode2.key=key;
  newNode2.value=value;
  newNode2.next=null;

 Node2 temp=table[newNode2.hash];
  
  Node2 ItLast=null;
  boolean keyRepeat=false;
  if (temp==null) {//如果此处的节点为空,直接放进去
   table[newNode2.hash]=newNode2;
   size++;
  }
  else {
   while(temp!=null) {
    if(temp.key.equals(newNode2.key)) {
     temp.value=newNode2.value;
     keyRepeat=true;
     break;
    }
    else {
     ItLast=temp;
     temp=temp.next;
    }
   }
   if (!keyRepeat) {
    ItLast.next=newNode2;
    size++;
   }
   
  }
  
 }

public V get(K key) {
  int hash=myHash(key.hashCode(), table.length);
  Object value=null;
  if (table[hash]!=null) {
   Node2 temp=table[hash];
   while (temp!=null) {
    if (temp.key.equals(key)) {
     value=temp.value;
     break;
    }
else {
     temp=temp.next;
    } 
   }
  }
  return (V)value;
 } 
 public static int myHash(int v,int length) {
  return v&(length-1);
 }
 @Override
 public String toString() {
  StringBuilder sb=new StringBuilder("{");
  for (int i = 0; i < table.length; i++) {//遍历数组
   Node2 temp=table[i];
   //遍历链表
   while (temp!=null) {
    sb.append(temp.key+":"+temp.value+",");
    temp=temp.next;
   }
  }
  sb.setCharAt(sb.length()-1, '}');
  return sb.toString();
 }
public static void main(String[] args) {
  TestMap4<Integer,String> m1=new TestMap4<>();
  System.out.println();
  m1.put(10, "aa");
  m1.put(20, "bb");
  m1.put(30, "cc");
  m1.put(18, "cc");
  m1.put(34, "sss");
  m1.put(50, "cc");
  m1.put(33, "4564");
  System.out.println(m1);

  System.out.println(m1.get(50));
  }

内容有点多,下一篇继续,我会把前几天的补上的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值