Java基础-List实现类&泛型


数据结构:

了解常用的数据结构:

栈、队列、堆、数据、链表、红黑树(二叉树)、图、哈希结构

    栈的特点:先进后出

队列的特点:先进先出


栈和队列的示例图:


数组数据结构和链表数据结构

数组数据结构的概念和特点:

概念:存储同一种数据类型元素的容器

特点:存在引用,可以按照索引查找

优点:查询快

缺点:增删慢

链表数据结构的概念和特点:

概念:把一些节点用链子连接起来的数据结构

优点:增删快

缺点:查询慢


链表结构和数组结构的示意图





List接口的三个实现子类的特点:

A:ArrayList类的特点:

底层是数组结构,查询快,增删慢;线程不安全,效率高

B:Vector类的特点:

底层是数组机构,查询快,增删慢;线程安全,效率低

C:LinkedList类的特点:

底层是链表结构,增删快,查询慢;线程不安全,效率低


例题:
                               一个字符串集合ArrayList中含有如下元素:hello, world, java, 
hello, java, php, android,world。要求编写程序,获得一个没有重复元素的新集合。
          

思路:

1 创建两个集合对象一个老集合,一个新集合
2 给老集合中添加元素
3 遍历老集合得到老集合中的每一个数据
4 再得到老集合中的数据后用新集合进行判断,判断集合中是否包含数据,
如果不包含,则把数据添加到新集合当中,如果包含不添加


代码:

public class Test1 {
	public static void main(String[] args) {
		// 创建一个集合,添加上面的元素
		Collection c = new ArrayList();
		// 创建一个新的集合
		Collection c1 = new ArrayList();
		// 添加元素
		c.add("hello");
		c.add("world");
		c.add("java");
		c.add("hello");
		c.add(".net");
		c.add("java");
		c.add("php");
		c.add("ios");
		c.add("java");
		c.add("android");
		c.add("world");
		System.out.println("c: " + c);
		System.out.println("c1: " + c1);
		// 遍历集合
		// 获取迭代器
		Iterator it = c.iterator();
		// 遍历
		while (it.hasNext()) {
			String s = (String)it.next();
			if(!(c1.contains(s))){
				c1.add(s);
			}
			//System.out.println(c1.contains(it.next()));
			// if(!(c1.contains(it.next()))){
			// c1.add(it.next());

		}
		System.out.println("c1:" + c1);

	}

}
结果:

例题:

ArrayList存储自定义对象去重复

代码:

import java.util.ArrayList;
import java.util.Iterator;

public class Test2 {
	public static void main(String[] args) {
		// 创建一个集合
		ArrayList<Student> array = new ArrayList<>();
		// 创建第二个集合
		ArrayList<Student> array2 = new ArrayList<>();
		// 创建Student对象
		Student s1 = new Student("小苍", 20);
		Student s2 = new Student("苍井", 20);
		Student s3 = new Student("小龙", 21);
		Student s4 = new Student("小龙", 21);
		Student s5 = new Student("苍井", 21);
		Student s6 = new Student("小泽", 18);
		// 向集合array添加Student对象
		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);
		array.add(s5);
		array.add(s6);

		// 遍历array集合
		Iterator it = array.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			if (!(array2.contains(s))) {
				array2.add(s);
			}
		}
		/*
		 *  输出去重后的集合,由于集合arrays中存储的是Student对象的引用
		 *  因此,我们需要遍历每一个元素,然后输入每一个对象中对应的属性
		 */
		System.out.println("去重后的集合: " + array2);
		for(int x=0;x<array2.size();x++){
			Student s = array2.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}

	}
}
结果:


重点学习ArrayList

ArrayList存储字符串并遍历

代码如下:

import java.util.ArrayList;
import java.util.Iterator;

/*
 * ArrayList存储字符串并遍历
 * 
 * 作业:用ArrayList存储自定义对象并遍历。
 */
public class ArrayListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		ArrayList array = new ArrayList();

		// 创建并添加元素
		array.add("hello");
		array.add("world");
		array.add("java");

		// 遍历集合
		Iterator it = array.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}

		System.out.println("-----------");

		// for (int x = 0; x < array.size(); x++) {
		// String s = (String) array.get(x);
		// System.out.println(s);
		// }
		// 开发中,我会按照如下方式写,请问为什么?
		//上面那种方式,每次都会调用size()方法,效率低。
		//下面这种方式,我们只调用一次。效率较高。
		int length = array.size();
		for (int x = 0; x < length; x++) {
			String s = (String) array.get(x);
			System.out.println(s);
		}
	}
}

ArrayList中存储自定义对象,然后遍历

代码:

import java.util.ArrayList;
import java.util.Iterator;

/*
 * ArrayList存储自定义对象并遍历
 */
public class ArrayListDemo2 {
	public static void main(String[] args) {
		ArrayList array = new ArrayList();

		Student s1 = new Student("乔峰", 40);
		Student s2 = new Student("虚竹", 36);
		Student s3 = new Student("段誉", 28);

		array.add(s1);
		array.add(s2);
		array.add(s3);

		Iterator it = array.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + "***" + s.getAge());
		}

		System.out.println("-------------");

		for (int x = 0; x < array.size(); x++) {
			Student s = (Student) array.get(x);
			System.out.println(s.getName() + "***" + s.getAge());
		}
	}
}

结果:




例题:

* ArrayList如果存储的是学生,那么,怎么去除重复元素呢?
  * 问题:如何知道学生是重复的。
  * 需求:如果学生的姓名和年龄相同,我就认为是同一个学生。即重复值。
 * 
 * 通过简单分析,我们估计是判断那里出问题了。
 * 怎么办呢?
 * 看判断的方法。
 * 而我们又知道,判断的方法是API提供的。不是自己的写的。
  * 看源码,看底层到底怎么实现的。
  * 通过看源码,我们发现,底层依赖的是equals()。
 * 由于学生类中,我们并没有equals()方法,所以,默认用的是Object的方法。
  * 而Object类的方法,默认比较的是地址值。
  * 由于学生对象都是new出来的,地址值肯定不一样,所以从这个角度考虑结论是正确的。
  * 但是不符合我们的需求。
  * 肿么办?
 * 重写equals(),让他按照我们的需要来比较。



代码如下:

public class ArrayListTest3 {
	public static void main(String[] args) {
		ArrayList array = new ArrayList();

		Student s1 = new Student("郑成功", 40);
		Student s2 = new Student("戚继光", 50);
		Student s3 = new Student("戚继光", 50);
		Student s4 = new Student("岳飞", 36);
		Student s5 = new Student("岳飞", 40);
		Student s6 = new Student("林则徐", 30);

		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);
		array.add(s5);
		array.add(s6);

		// 创建新集合
		ArrayList array2 = new ArrayList();

		// 遍历旧集合,获取到每一个元素
		Iterator it = array.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			// 在新集合中判断,看是否存在这个元素
			if (!array2.contains(s)) {
				// 如果s不再array2中存在,就添加
				array2.add(s);
			}
		}

		// array2就是没有重复元素的集合。
		// 遍历array2
		for (int x = 0; x < array2.size(); x++) {
			Student s = (Student) array2.get(x);
			System.out.println(s.getName() + "***" + s.getAge());
		}
	}
}


Student类代码:

public class Student {
	private String name;
	private int age;

	public Student() {
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public boolean equals(Object obj) {
		// 提高效率
		if (this == obj) {
			return true;
		}

		// 提高健壮性
		if (!(obj instanceof Student)) {
			return false;
		}

		// 向下转换
		Student s = (Student) obj;
		return this.name.equals(s.name) && this.age == s.age;
	}
}


Vector的特有功能:

* Vector的特有功能:
 * A:添加功能
升级后方法
 * public void addElement(Object obj) -- add(Object obj)
  * B:获取功能
  * public Object elementAt(int index)-- get(int index)
 * public Enumeration elements()-- Iterator
  * boolean hasMoreElements()-- hasNext()
  * Object nextElement()--  next()
  * C:长度功能
  * public int size()
 * 
  * JDK版本升级:
  * A:安全
  * B:效率
  * C:简化书写


Vector类特有方法代码;

public class VectorDemo {
	public static void main(String[] args) {
		// 创建集合对象
		Vector v = new Vector();

		// 添加元素
		v.addElement("hello");
		v.addElement("world");
		v.addElement("java");

		// 遍历
		// System.out.println(v.elementAt(0));
		// System.out.println(v.elementAt(1));
		// System.out.println(v.elementAt(2));
		for (int x = 0; x < v.size(); x++) {
			String s = (String) v.elementAt(x);
			System.out.println(s);
		}
		
		System.out.println("----------------");
		
		//public Enumeration elements()
		Enumeration en = v.elements();
		while(en.hasMoreElements()){
			String s = (String)en.nextElement();
			System.out.println(s);
		}
	}
}

结果


LinkedList的特有方法:

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


代码:

public class LinkedListDemo {
	public static void main(String[] args) {
		LinkedList link = new LinkedList();

		link.add("hello");
		link.add("world");
		link.add("java");

		// 添加功能
		// link.addFirst("EE");
		// link.addLast("ME");

		// 获取功能
		// System.out.println("getFirst:"+link.getFirst());
		// System.out.println("getLast:"+link.getLast());

		// 删除功能
		System.out.println("removeFirst:" + link.removeFirst());
		System.out.println("removeLast:" + link.removeLast());

		System.out.println("link:" + link);
	}
}
结果:

分析结果可知,LinkedList方法中的remove功能,影响结合中的元素


面试题:

通过LinkedList模拟栈数据结构
  要模拟的内容的特点:
  先进后出。

  通过LinkedList模拟栈数据结构: 它的意思是说,你有一个LinkedList可以用,但是,你需要自己定义一个栈集合。
对外提供获取和添加功能。


实现栈结构代码:

import java.util.LinkedList;

/*
 * 自定义栈集合。
 */
public class MyStack {
	private LinkedList link;

	public MyStack() {
		link = new LinkedList();
	}

	public void add(Object obj) {
		link.addFirst(obj);
	}

	public Object get(int index) {
		return link.get(index);
	}

	public int size() {
		return link.size();
	}
}
使用自定义栈结构代码;

public class LinkedListTest {
	public static void main(String[] args) {
		

		// 创建集合对象
		MyStack ms = new MyStack();

		// 创建并添加元素
		ms.add("hello");
		ms.add("world");
		ms.add("java");

		// 获取
		// System.out.println(ms.get(0));
		// System.out.println(ms.get(1));
		// System.out.println(ms.get(2));
		// System.out.println(ms.get(3));

		for (int x = 0; x < ms.size(); x++) {
			String s = (String) ms.get(x);
			System.out.println(s);
		}
	}
}

结果

分析结果:实现了栈的特点:先进后出



泛型:

  ClassCastException:类型转换问题
  
  泛型:任意的类型。是一种把明确数据类型的工作放在了创建对象或者调用方法 时候进行的特殊的类型。
  
  泛型的格式:
  <数据类型>
  
  为什么会有泛型? 就是为了解决黄线和类型转换问题。
  怎么解决呢?
 
就是模仿数组解决的,在定义集合的时候,告诉集合,你只能存储什么类型的元 素。
  怎么告诉呢,通过泛型。
  
  泛型的好处:
  A:解决黄色警告线问题。
  B:把运行期间的类型转换异常提前到了编译期间。
  C:优化程序设计。
  
 
泛型在哪些地方用啊?
  别问我,问API。如果类或者接口后面有<>,那么这就是泛型的体现。它就
是要你在使用的时候明确类型的。
  泛型一般就在集合中用。

代码:

<span style="font-size:24px;">public class ArrayListDemo {
	public static void main(String[] args) {
		// 用ArrayList存储字符串并遍历
		ArrayList<String> array = new ArrayList<String>();

		array.add("hello");
		array.add("world");
		array.add("java");
		// array.add(10);// 等价于array.add(new Integer(10));

		Iterator<String> it = array.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
			// System.out.println(it.next());
		}

		// 数组在定义的时候,就明确告诉你了,我们的元素是某种固定的类型。不能是其他类型。
		// String[] strArray = new String[3];
		// strArray[0] = "hello";
		// strArray[1] = "world";
		// strArray[2] = 0;

	}
}
</span>


增强for循环


 
* 格式:
  * for(数组或者Collection集合中元素类型 变量名 : 数组或者Collection 集合对象)
  * {
  * 使用变量名即可。
  * }
 * 
  * 作用:简化数组和Collection集合的变量。
  * 注意:增强for是用来替代迭代器的。不能再用增强for的时候,用集合对象对集合进行改变。


代码:

public class ForDemo {
	public static void main(String[] args) {
		// 整型数组
		int[] arr = { 1, 2, 3, 4, 5 };
		// 普通for
		for (int x = 0; x < arr.length; x++) {
			System.out.println(arr[x]);
		}
		System.out.println("--------------");
		// 增强for
		for (int x : arr) {
			System.out.println(x);
		}
		System.out.println("--------------");

		// 字符串数组
		String[] strArray = { "hello", "world", "java" };
		// 增强for
		for (String str : strArray) {
			System.out.println(str);
		}
		System.out.println("--------------");

		// 集合
		ArrayList<String> array = new ArrayList<String>();
		array.add("hello");
		array.add("world");
		array.add("java");
		for (String str : array) {
			System.out.println(str);
		}
		System.out.println("--------------");

		// 增强for和迭代器我们一般只选一种。
		// 增强for是来替代迭代器的。
		// ArrayList<String> array2 = new ArrayList<String>();
		// array2.add("hello");
		// array2.add("world");
		// array2.add("java");
		// ConcurrentModificationException

		ArrayList<String> array2 = null;
		// NullPointerException
		for (String str : array2) {
			if (str.equals("world")) {
				array2.add("EE");
			}
		}
	}
}
结果










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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值