集合框架-ArrayList,Vector,Linkedlist

时间:2021-02-23 04:27:03

// ClassCastException 报错,注意,千万要搞清楚类型

 

* Vector的特有功能:
* 1:添加功能
* public void addElement(Object obj) -- 被add()替代
* 2:获取功能
* public Object elementAt(int index) -- 被 get()替代
* public Enumeration elements() -- 被Iterator iterator()替代
* boolean hasMoreElements() -- 被 hasNext()替代
* Object nextElement() -- 被 next()替代
*
* JDK升级的原因:
* A:安全
* B:效率
* C:简化书写

 1         // 创建集合对象
 2         Vector v = new Vector();
 3 
 4         // 添加功能
 5         v.addElement("hello");
 6         v.addElement("world");
 7         v.addElement("java");
 8 
 9         // 遍历
10         for (int x = 0; x < v.size(); x++) {
11             String s = (String) v.elementAt(x);
12             System.out.println(s);
13         }
14 
15         System.out.println("------------------");
16 
17         Enumeration en = v.elements(); // 返回的是实现类的对象
18         while (en.hasMoreElements()) {
19             String s = (String) en.nextElement();
20             System.out.println(s);
21         }

 

* LinkedList的特有功能:
* A:添加功能
* public void addFirst(Object e)
* public void addLast(Object e)
* B:获取功能
* public Object getFirst()
* public Obejct getLast()
* C:删除功能
* public Object removeFirst()
* public Object removeLast()

 

* ArrayList去除集合中字符串的重复值(字符串的内容相同)
*
* 分析:
* A:创建集合对象
* B:添加多个字符串元素(包含内容相同的)
* C:创建新集合
* D:遍历旧集合,获取得到每一个元素
* E:拿这个元素到新集合去找,看有没有
* 有:不搭理它
* 没有:就添加到新集合
* F:遍历新集合

 1         // 创建集合对象
 2         ArrayList array = new ArrayList();
 3 
 4         // 添加多个字符串元素(包含内容相同的)
 5         array.add("java");
 6         array.add("world");
 7         array.add("java");
 8         array.add("world");
 9 
10         // 创建新集合
11         ArrayList newArray = new ArrayList();
12 
13         // 遍历旧集合,获取得到每一个元素
14         Iterator it = array.iterator();
15         while (it.hasNext()) {
16             String s = (String) it.next();
17 
18             // 拿这个元素到新集合去找,看有没有
19             if (!newArray.contains(s)) {
20                 newArray.add(s);
21             }
22         }
23 
24         // 遍历新集合
25         for (int x = 0; x < newArray.size(); x++) {
26             String s = (String) newArray.get(x);
27             System.out.println(s);
28         }
29     }

 

方法二:

* 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
* 要求:不能创建新的集合,就在以前的集合上做。

 1         // 由选择排序思想引入,我们就可以通过这种思想做这个题目
 2         // 拿0索引的依次和后面的比较,有就把后的干掉
 3         // 同理,拿1索引...
 4         for (int x = 0; x < array.size() - 1; x++) {
 5             for (int y = x + 1; y < array.size(); y++) {
 6                 if (array.get(x).equals(array.get(y))) {
 7                     array.remove(y);
 8                     y--;
 9                 }
10             }
11         }

 

* 需求:去除集合中自定义对象的重复值(对象的成员变量值都相同)
*
* 我们按照和字符串一样的操作,发现出问题了。
* 而这个判断功能是集合自己提供的,所以我们如果想很清楚的知道它是如何判断的,就应该去看源码。
* contains()方法的底层依赖的是equals()方法。
* 而我们的学生类中没有equals()方法,这个时候,默认使用的是它父亲Object的equals()方法
* Object()的equals()默认比较的是地址值,所以,它们进去了。因为new的东西,地址值都不同。
* 按照我们自己的需求,比较成员变量的值,重写equals()即可。
* 自动生成即可。

 

*请用LinkedList模拟栈数据结构的集合,并测试
*题目的意思是:
* 你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟。

 1 public class MyStack {
 2     private LinkedList link;
 3 
 4     public MyStack() {
 5         link = new LinkedList();
 6     }
 7 
 8     public void add(Object obj) {
 9         link.addFirst(obj);
10     }
11 
12     public Object get() {
13         // return link.getFirst();
14         return link.removeFirst();
15     }
16 
17     public boolean isEmpty() {
18         return link.isEmpty();
19     }
20 }

 

* 集合也模仿着数组的这种做法,在创建对象的时候明确元素的数据类型。这样就不会在有问题了。
* 而这种技术被称为:泛型。
*
* 泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
* 格式:
* <数据类型>
* 此处的数据类型只能是引用类型。
* 好处:
* A:把运行时期的问题提前到了编译期间
* B:避免了强制类型转换
* C:优化了程序设计,解决了黄色警告线

 

// 创建集合对象
// JDK7的新特性:泛型推断。
// ArrayList<Student> array = new ArrayList<>();
// 但是我不建议这样使用。

 

* 早期的时候,我们使用Object来代表任意的类型。
* 向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题。
* 也就是说这样的程序其实并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。

 1 public class ObjectTool {
 2     private Object obj;
 3 
 4     public Object getObj() {
 5         return obj;
 6     }
 7 
 8     public void setObj(Object obj) { // Object obj = new Integer(30);
 9         this.obj = obj;
10     }
11 }
 1 /*
 2  * 泛型类:把泛型定义在类上
 3  */
 4 public class ObjectTool<T> {
 5     private T obj;
 6 
 7     public T getObj() {
 8         return obj;
 9     }
10 
11     public void setObj(T obj) {
12         this.obj = obj;
13     }
14 }

 

/*
* 泛型方法:把泛型定义在方法上
*/

1 public class ObjectTool {
2     public <T> void show(T t) {
3         System.out.println(t);
4     }
5 }

 

/*
* 泛型接口:把泛型定义在接口上
*/

1 public interface Inter<T> {
2     public abstract void show(T t);
3 }
1 public class InterImpl<T> implements Inter<T> {
2 
3     @Override
4     public void show(T t) {
5         System.out.println(t);
6     }
7 }

 

// 泛型如果明确的写的时候,前后必须一致
Collection<Object> c1 = new ArrayList<Object>();
Collection<Object> c2 = new ArrayList<Animal>(); //报错
Collection<Object> c3 = new ArrayList<Dog>(); //报错

 

* 泛型高级(通配符)
* ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
* ? extends E:向下限定,E及其子类
* ? super E:向上限定,E极其父类

 1         // ?表示任意的类型都是可以的
 2         Collection<?> c5 = new ArrayList<Object>();
 3         Collection<?> c6 = new ArrayList<Animal>();
 4         Collection<?> c7 = new ArrayList<Dog>();
 5         Collection<?> c8 = new ArrayList<Cat>();
 6 
 7         // ? extends E:向下限定,E及其子类
 8         // Collection<? extends Animal> c9 = new ArrayList<Object>(); //报错
 9         Collection<? extends Animal> c10 = new ArrayList<Animal>();
10         Collection<? extends Animal> c11 = new ArrayList<Dog>();
11         Collection<? extends Animal> c12 = new ArrayList<Cat>();
12 
13         // ? super E:向上限定,E极其父类
14         Collection<? super Animal> c13 = new ArrayList<Object>();
15         Collection<? super Animal> c14 = new ArrayList<Animal>();
16         // Collection<? super Animal> c15 = new ArrayList<Dog>(); //报错
17         // Collection<? super Animal> c16 = new ArrayList<Cat>(); //报错

 

* JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举
*
* 增强for:是for循环的一种。
*
* 格式:
* for(元素数据类型 变量 : 数组或者Collection集合) {
* 使用变量即可,该变量就是元素
* }
*
* 好处:简化了数组和集合的遍历。
*
* 弊端: 增强for的目标不能为null。
* 如何解决呢?对增强for的目标先进行不为null的判断,然后在使用。

// 说白了,这就是迭代器的功能

1         if (list != null) {
2             for (String s : list) {
3                 System.out.println(s);
4             }
5         }

 

* 静态导入:
* 格式:import static 包名….类名.方法名;
* 可以直接导入到方法的级别
*
* 静态导入的注意事项:
* A:方法必须是静态的
* B:如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
*/
import static java.lang.Math.abs;
import static java.lang.Math.pow;
import static java.lang.Math.max;

 

// 需求:我要写一个求和的功能,到底是几个数据求和呢,我不太清楚,但是我知道在调用的时候我肯定就知道了
// 为了解决这个问题,Java就提供了一个东西:可变参数

* 可变参数:定义方法的时候不知道该定义多少个参数
* 格式:
* 修饰符 返回值类型 方法名(数据类型… 变量名){
*
* }
*
* 注意:
* 这里的变量其实是一个数组
* 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

 1     public static int sum(int... a) {
 2         // System.out.println(a);
 3         //return 0;
 4 
 5         int s = 0;
 6         
 7         for(int x : a){
 8             s +=x;
 9         }
10         
11         return s;
12     }

 

* public static <T> List<T> asList(T... a):把数组转成集合
*
* 注意事项:
* 虽然可以把数组转成集合,但是集合的长度不能改变。

 1         List<String> list = Arrays.asList("hello", "world", "java");
 2         // UnsupportedOperationException
 3         // list.add("javaee");
 4         // UnsupportedOperationException
 5         // list.remove(1);
 6         list.set(1, "javaee");
 7 
 8         for (String s : list) {
 9             System.out.println(s);
10         }

 

 * 获取10个1-20之间的随机数,要求不能重复

 1         // 创建产生随机数的对象
 2         Random r = new Random();
 3 
 4         // 创建一个存储随机数的集合。
 5         ArrayList<Integer> array = new ArrayList<Integer>();
 6 
 7         // 定义一个统计变量。从0开始。
 8         int count = 0;
 9 
10         // 判断统计遍历是否小于10
11         while (count < 10) {
12             //先产生一个随机数
13             int number = r.nextInt(20) + 1;
14             
15             //判断该随机数在集合中是否存在。
16             if(!array.contains(number)){
17                 //如果不存在:就添加,统计变量++。
18                 array.add(number);
19                 count++;
20             }
21         }
22         
23         //遍历集合
24         for(Integer i : array){
25             System.out.println(i);
26         }
27     }

 

* 键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最大值

 1         // 创建键盘录入数据对象
 2         Scanner sc = new Scanner(System.in);
 3 
 4         // 键盘录入多个数据,我们不知道多少个,所以用集合存储
 5         ArrayList<Integer> array = new ArrayList<Integer>();
 6 
 7         // 以0结束,这个简单,只要键盘录入的数据是0,我就不继续录入数据了
 8         while (true) {
 9             System.out.println("请输入数据:");
10             int number = sc.nextInt();
11             if (number != 0) {
12                 array.add(number);
13             } else {
14                 break;
15             }
16         }
17 
18         // 把集合转成数组
19         // public <T> T[] toArray(T[] a)
20         Integer[] i = new Integer[array.size()];
21         array.toArray(i);
22 
23         // 对数组排序
24         // public static void sort(Object[] a)
25         Arrays.sort(i);
26 
27         // 获取该数组中的最大索引的值
28         System.out.println("数组是:" + arrayToString(i) + "最大值是:"
29                 + i[i.length - 1]);
30 
31 
32     public static String arrayToString(Integer[] i) {
33         StringBuilder sb = new StringBuilder();
34 
35         sb.append("[");
36         for (int x = 0; x < i.length; x++) {
37             if (x == i.length - 1) {
38                 sb.append(i[x]);
39             } else {
40                 sb.append(i[x]).append(", ");
41             }
42         }
43         sb.append("]");
44 
45         return sb.toString();
46     }