CTRL+P
手写一个排序 快排排序 用户实体类中的年龄
package org.example;
import java.util.ArrayList;
import java.util.List;
/**
* 對象排序
* List Userinfos 規定按照用戶的年齡進行排序 從高到低
* fanxing泛型
*/
//泛型类 在构建本类对象时就告知该对象中的这个泛型是什么类型 建造对象时临时指定泛型类型
public class MyObjectSort {
static List<Userinfos> uss = new ArrayList<Userinfos>();
static{
uss.add(new Userinfos(1,"zs",20));
uss.add(new Userinfos(2,"ls",18));
uss.add(new Userinfos(3,"ww",44));
uss.add(new Userinfos(4,"zl",32));
uss.add(new Userinfos(5,"sq",55));
uss.add(new Userinfos(6,"wb",70));
}
public void quick(int low,int high) {
int lo=low,hi=high;
if ( lo >= hi ) {
return;
}
boolean flag = false;
while ( lo < hi ) {
if ( uss.get(lo).compareTo(uss.get(hi)) == 0) {
Userinfos temp = uss.get(lo);
uss.set(lo,uss.get(hi));
uss.set(hi,temp);
flag=!flag;
}
if (flag)
lo++;
else
hi--;
}
lo--;hi++;
quick(low,lo);
quick(hi,high);
}
public static void main(String[] args) {
MyObjectSort mos = new MyObjectSort();
mos.quick(0,5);
System.out.println(mos);
}
}
package org.example;
public class Userinfos implements Comparable<Userinfos>{
private int userid;
private String username;
private int age;
@Override
public int compareTo(Userinfos o) {
if ( this.age > o.getAge() ) {
return 1;
} else {
return 0;
}
}
public Userinfos() {
}
public Userinfos(int userid, String username, int age) {
this.userid = userid;
this.username = username;
this.age = age;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
手写一个 hashmap底层源码 以及一些方法
使用的是数组加链表 JDK1.7以前的方法
package org.example;
public class MyMap<K,V> {
transient int size;//你的Map中所有元素的个数
private static final int DEFAULT_CAPACITY=1<<4;//hash表默认容量
private static final int DEFAULT_THRESHOLD=1<<3;//默认阈值
transient Node<K,V> [] table;
public MyMap(){
table = new Node[DEFAULT_CAPACITY];
}
public void put(K key,V value) {
//计算hash值
int hash = hash(key);
//根据hash值找到数据应该存放的位置求余
int pos = hash%table.length;
//到数组中查看该位置是否已经有数据链表如果有就遍历链表 如果链表中已经有该数据则 替换对应的值 否则把数据添加到链表的尾部
if( table[pos] == null ) {
//空的就直接构建1个链表
Node<K,V> newNode = new Node<K,V>(hash,key,value,null);
table[pos]=newNode;
size++;
}else {
//如果位置上不空
//检查用户传入的key是否和链表中的key重复 如果重复就用用户传入的value值替换对应的值
Node<K,V> x=table[pos];//开始时存放链表头部
Node<K,V> last = null;//存放链表的尾部
do {
if (x.key == key) {
//进行数据覆盖
x.value = value;
break;
}
last = x;
}while( (x=x.next) != null);
if ( x == null ){
Node<K,V> newNode = new Node<K,V>(hash,key,value,null);
last.next = newNode;
size++;
}
}
}
/**
* 查找数据是否存在
* @param key
* @return
*/
public boolean contains(K key) {
return true;
}
private int hash(K key) {
if ( key == null ) {
return 0;
}else {
int h = key.hashCode();
return Math.abs(h^(h>>>16));
}
}
private static class Node<K,V> {
private long hashCode;
private K key;
private V value;
private Node<K,V> next;
public Node() {
}
public Node(long hashCode, K key, V value, Node<K, V> next) {
this.hashCode = hashCode;
this.key = key;
this.value = value;
this.next = next;
}
public long getHashCode() {
return hashCode;
}
public void setHashCode(long hashCode) {
this.hashCode = hashCode;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node<K, V> getNext() {
return next;
}
public void setNext(Node<K, V> next) {
this.next = next;
}
}
}
package org.example;
public class MyLink<T> {
transient int size;//存放元素的个数
transient Node<T> first;//存放首环地址
transient Node<T> last;//存放尾环地址
public MyLink(){}
/**
* 把一个元素存放到链表中,通常存放在链表的末尾
* @param item
*/
public void add(T item) {
//建造一个Node对象
Node<T> newNode = new Node<T>(null,item,null);
//判断是否是首次添加一环
if ( first == null && last == null ) {
//直接将建造的对象存放到first和last中
first = newNode;
last = newNode;
}else {
//不是首环
//将尾环的next设置为新环
last.next = newNode;
//将新环的prev设置为last环
newNode.prev = last;
//再将新环存放到last中
last = newNode;
}
size++;
}
/**
* 移除链表中的一个元素 自己添加
* @param t
*/
public void remove(T t) {
//根据用户传入的元素搜索Node
Node<T> x = first;
int i =0;
for ( ; i < size; i++) {//size :10 .... 下标 9
if (x.item == t) {
//如果元素的值等于你需要找的值 那么久退出循环 此时i一定小于size
break;
}else {
//如果元素节点值不等于就把节点换成下个节点
x = x.next;
}
}
//一直找不到 退出循环时一定是10
//判断是否找到对应元素 i<size说明找到了对应的元素
if ( i < size ) {
if ( x == first ) {
//判断该节点是否是首环 ,首环只要把下一环的prev设置为空 并将first属性设置为下一环
first = first.next;
first.prev = null;
}else if ( x == last ) {
//判断节点是否是尾环, 尾环要将上一环的next设置为空 并将last属性设置为上一环
last = last.prev;
last.next=null;
}else {
//如果是中间环,则把上一环的next设置为当前环的下一环 把下一环的prev设置成当前环的上一环
x.prev.next=x.next;
x.next.prev=x.prev;
}
size--;
}
}
/**
* 获取链表中的一个指定位置的元素
* @param index
* @return
*/
public T get(int index) {
//检查用户用户传入的下标是否合法
if ( index+1 > size || index < 0 )
throw new IndexOutOfBoundsException("下标溢出");
//根据用户给定的下标如果在链表的前半截 就从头搜索 如果在后半截就 从尾向头搜
if ( index < (size >> 1 ) ) {
Node<T> x = first;
for ( int i = 0 ; i < index; i++ )
x = x.next;
return x.item;
}else {
Node<T> x = last;
for ( int i = size-1; i > index; i-- )
x = x.prev;
return x.item;
}
}
/**
* 向头部添加一环
* @param t
*/
public void addFirst(T t) {
Node<T> newFirst = new Node<T>(null,t,null);
first.prev = newFirst;
newFirst.next = first;
first = newFirst;
size++;
}
/**
* 向链表的尾部加入一环
* @param t
*/
public void addLast(T t) {
add(t);
}
/**
* 根据用户给定的位置 修改元素信息
* @param index
* @param element
*/
public void set(int index,T element){
//根据元素位置 搜索元素
Node<T> x = first;
for ( int i=0; i< index ;i++ ) {
x=x.next;
}
x.item = element;
}
//内部类 生成环节点
private static class Node<T> {
T item;
Node<T> prev;
Node<T> next;
public Node(Node<T> prev,T item, Node<T> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
}
@Override
public String toString() {
String str = "[";
Node<T> x = first;
for ( int i=0; i<size ;i++) {
str+=x.item+",";
x=x.next;
}
str = str.substring(0, str.length()-1)+"]";
return str;
}
}
package com.myh.testkb;
import java.util.LinkedList;
import java.util.List;
public class Test<T> {
transient Node <T>first;
transient Node <T>last;
transient int size;
private class Node<T>{
T item;
Node<T> next;
public Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
}
public static void main(String[] args) {
int t=99999999;
String a[]=new String[t];
for (int i = 0; i < a.length; i++) {
a[i]="asdfg";
}
a[a.length-1]="asdf";
List <String>l1= new LinkedList<>();
for (int i = 0; i < t; i++) {
if(i<t-1){
l1.add("asdfg");
}else {
l1.add("asdf");
}
}
long time=System.currentTimeMillis();
for (int i = 0; i < a.length/2; i++) {
if(a[i].equals("asdf")){
break;
}
}
System.out.println("第一个:"+ (System.currentTimeMillis()-time));
//
time=System.currentTimeMillis();
l1.get(t/2-1);
System.out.println("第二个:"+ (System.currentTimeMillis()-time));
}
}
亲自实验 比较时间复杂度
我找某个值
分别用 fori 数组一个一个比对, 第二种用链表 用x.next方法一个一个往后找。
最后因为后者要找地址 所以速度要慢于前面的。
数值99999999的时候很吃内存 但确实是 链表速度慢些
换种情况 数值小的时候一百万的时候 就是链表更快了