package cm;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class test20180409 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
// int[] data = {1,2,3,4,5};
//
// List list = Arrays.asList(data);
//
// System.out.println("列表中的元素数量是:" + list.size());
// 注意这里输出的数量是1,原因是,在Arrays.asList中,该方法接受一个变长参数,一般可看做数组参数,但是因为int[]
// 本身就是一个类型,所以data变量作为参数传递时,编译器认为只传了一个变量,这个变量的类型是int数组,所以size为1。基本类型是不能作为泛型的参数,按道理应该使用包装类型,但这里缺没有报错,因为数组是可以泛型化的,所以转换后在list中就有一个类型为int的数组
// List ss=Arrays.asList("a","b");
// ss.add("s");这里使用add方法会出错,因为使用arrays.aslist()方法处理过的数据,返回的list类型,已经不是传统意义上的list了,此list没有实现add方法,需要自己手动实现
// List常用的有两种实现Arraylist和LinkedList
// ArrayList的特点在于随机访问元素,内部由数组实现,缺点插入和移除元素比linkedList开销大。
// 接口List最重要的特点是次序,它维护了元素的特定顺序.一个List可以生成listiterator,用于遍历list中的元素
// LinkedList中的方法addfirst(),addLast(),getfirst(),getLast(),removefirst(),removelast()使得Linkedlist可以当做堆栈,队列,双向队列等数据结构使用。
// List a = new LinkedList();
// a.add("1");
// a.add("2");
// a.add(1, "3");// 将3插入index为1处
// ArrayList arr = new ArrayList();
// arr.add("Hi");
// a.addAll(arr);// 将一个collection添加进linkedlist
// a.addAll(1, arr);// 将一个collection从index为1处开始添加
// Boolean is = a.contains("1");// true 检车linkedlist中是否包含字符串1.
// Boolean isarr = a.containsAll(arr);// true 判断linked中是否包含arr容器。
// String str = a.get(1).toString();// 返回索引为1的对象,调用对象的tostring将对象以可读的方式输出。
// int index = a.indexOf("Hi");// 返回第一个匹配的索引。
// boolean isempty = a.isEmpty();// 判断LinkedList容器是否为空
// a.remove(3);// 移除索引为3的元素
// a.remove("Hi");// 移除元素Hi
// ;// 将索引为1处的元素改为be3
// a.removeAll(arr);// 参照容器arr将a中元素移除
// // a.clear();//清除a中的所有元素
// Iterator it = a.iterator();// 将容器Linkedlist转换为一个迭代器
// ListIterator itt = a.listIterator();//
// 将容器linkedlist转换成listiterator。listiterator和iterator的主要区别是
// listiterator只能应用于list集合,及其子集,而iterator能应用于所有集合。listiterator支持向前和向后遍历,而iterator只支持向后遍历。listiterator还支持向集合中添加元素add()方法
// // Iterator it3=a.listIterator(1);//将容器Linkedlist转换为一个迭代器,从容器索引为3的地方开始。
// boolean hn = itt.hasNext();// 判断迭代器中是否还有下一个元素
// Boolean hp = itt.hasPrevious();
// String sn = (String) itt.next();
// int ni=itt.nextIndex();
// String sp = (String) itt.previous();
// int pi=itt.previousIndex();
// itt.add("47");//向listiterator中添加元素
// P.sopl(isarr + "");
// P.sopl(is + "");
// P.sopl(a + "");
// P.sopl(str);
// P.sopl(index + "");
// P.sopl(isempty + "");
// P.sopl(hn + "");
// P.sopl(hp + "");
// P.sopl(sn);
// P.sopl(ni+"");
// P.sopl(sp);
// P.sopl(pi+"");
// 使用Linkedlist制作一个栈(后进先出结构)
// stacklist st=new stacklist();
// st.push(new String("i love you"));
// st.push(new String("i love you too"));
// P.sopl(st.top().toString());
// P.sopl(st.pop().toString());
// P.sopl(st.top().toString());
// 使用linkedlist制作一个队列,即先进先出结构,可用来制作queue类
// queuelist ql=new queuelist();
// ql.put(new String("ok"));
// P.sopl(""+ql.isEmpty());
// P.sopl(""+ql.get());
// P.sopl(""+ql.isEmpty());
// set的功能和方法
// 前提:set集合不保存相同的元素,存入set的元素必须实现equals方法用于判断元素的唯一性,set和collection接口具有完全一样的接口。set不保证存入元素的次序。
// hashset目的是为了实现快速查找,存入hashset的元素对象必须实现hashcode()方法。treeset是保持次序的set,它可以从set中提取有序的序列,比较顺序是按照元素的comperto比较方法进行比较的。
// linkedhashset,具有hashset的查询速度,内部使用链表维护元素的顺序,使用迭代器遍历set时,结果会以元素插入的顺序显示。
// settest sett = new settest();
// sett.test(new HashSet());
// sett.test(new TreeSet<>());
// sett.test(new LinkedHashSet<>());
// sortedset是treeset的一个接口,treeset是其的唯一实现。
// Map的功能方法
// P.sopl(Integer.toString(new
// String("o1dafk").hashCode()));//测试string类是否实现了hashcode方法。
// hashmap插入和查询键值对的开销是固定的,可以通过调整构造器来调整hashmap的容量和负载因子来调整hashmap的性能。
// linkedhashmap取得键值对的顺序是插入键值对的顺序,比hashmap慢一点,但是在使用迭代器访问时linkedhashmap快一些,因为linkedhashmap内部使用链表实现的。
// treemap取得键值对或则健的时候是经过排序的,次序由cpmpareable和cpmparator方法决定。
// weakhashmap,如果没有map之外的引用指向某个键,则此键将被回收。
// hashmap
// Map hm=new HashMap<>();
// Random rand=new Random();
// for (int i = 0; i < 10000; i++) {
// Integer in=new
// Integer(rand.nextInt(20));//为什么这里使用包装器类,because所有的容器都只能存放对象的引用,而不能存放基本类型
// if(hm.containsKey(in)) {
// ((counter)hm.get(in)).i++;//这里为什么用到自定义的counter类,而不用包装起来integer,因为包装器类只能在声明的时候读入一个值,也就是初始化一个值,并且读取这个值,生成一个对应类型的对象,之后就不能修改这个包装器的值了,没有提供对应的修改方法。
// }else {
// hm.put(in, new counter());
// }
// }
// P.sopl(hm.toString());
// Linkedhashmap
// LinkedHashMap<String,String> ls=new
// LinkedHashMap<>(20,0.1f,true);//第三个参数true用于实现LRU,根据访问顺序进行排序,最新访问的数据放在容器的最后。第一个参数13用于提供给这个类的基类用于初始化数组的容量,第二个参数代表负载因子。
// P.sopl(ls.getClass()+"");
// ls.put("1","a");
// ls.put("2","b");
// ls.put("3","c");
// ls.get("1");
// ls.get("2");
// for(Map.Entry<String, String> entry:ls.entrySet())
// {//使用Map接口的entry,Linkedhashmap类的entryset方法将容器中的键值对封装成一个一个的对象用于遍历
// P.sopl(entry.getKey()+entry.getValue());
// }
// // P.sopl(ls.toString());
// tips:调用类对象实例化一个对象
// 1. 通过类对象调用newInstance()方法,适用于无参构造方法:
// 例如:String.class.newInstance()
// Solution solution = Solution.class.newInstance();
// Solution solution2 = solution.getClass().newInstance();
// Class solutionClass = Class.forName("Solution");
// Solution solution3 = (Solution) solutionClass.newInstance();
// 2.通过类对象调用getConstructor()方法,此方法接受参数是一个Class类型的数组,数组中存放的是各个类类对象(类名.class),getConstructor()方法根据class数组中类对象的类型选择声明的构造器。
// Class []cs= {int.class};
// counter c=counter.class.getDeclaredConstructor(cs).newInstance(22);
// P.sopl(c.toString());
// hashcode算法和散列码
// 任何不特殊说明的类默认继承object基类,而object基类中的hashcode算法是根据对象的地址来生成散列码的。
// 测试
// counter ct = new counter();
// counter ct2 = new counter();
// P.sopl(Integer.toString(ct.hashCode()));
// P.sopl(Integer.toString(ct2.hashCode()));//
// 这两个对象完全一样,除了在堆中的地址不一样,所以生成的散列码就不一样。
//hashmap用equals方法判断传入的参数键是否存在于表中。hashmap中的equals方法并没有从写,而是继承了基类object中的equals方法,object中的equals方法只是比较两个引用(地址)是否相等,即是否指向同一个堆中的对象。
}
}
class stacklist {
private LinkedList<Object> list = new LinkedList<>();
public void push(Object o) {
list.addFirst(o);
}
public Object top() {
return list.getFirst();
}
public Object pop() {
return list.removeFirst();
}
}
class queuelist {
private LinkedList<Object> list = new LinkedList<>();
public void put(Object o) {
list.addFirst(o);
}
public Object get() {
return list.removeLast();
}
public Boolean isEmpty() {
return list.isEmpty();
}
}
class settest {
public static void fill(Set s) {
s.addAll(Arrays.asList("i love you do you".split(" ")));
}
public static void test(Set s) {
fill(s);
P.sopl(s.getClass().getName().replaceAll("\\w+\\.", ""));
P.sopl(s + "");
}
}
class counter {
int i = 1;
public counter(int x) {
i = x;
}
public String toString() {
return Integer.toString(i);
}
}