JavaSE——day13集合(2)、泛型

 

    继续讲ArrayList集合:ArrayList集合是List集合的一个常用类,ArrayList集合是线程不安全的,但是效率高,所以没有要求的情况下可以默认使用ArrayList集合存储对象。存储自定义变量并遍历的方法:

    (1)调用iterator迭代器

 

 

    (2)size()和get(int index)普通for循环。

如果集合中存储的是对象,那么以上两种方法同样适合,下面是对象数组Student的遍历例子:

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

public class Test2 {

	public static void main(String[] args) {
		//创建集合对象
		ArrayList<Student> s = new ArrayList<Student>() ;
		Student s1 = new Student("aloha", 22) ;
		Student s2 = new Student("alohaa",23) ;
		Student s3 = new Student("alohaaa",24) ;
		
		s.add(s1) ;
		s.add(s2) ;
		s.add(s3) ;
		
		//迭代器遍历
		Iterator<Student> it = s.iterator();
		while(it.hasNext()) {
			Student stu = it.next() ;
			System.out.println(stu.getName() + "---" + stu.getAge()); 
		}
		System.out.println("-----------------------------");
		//size()和set(int index)遍历
		for(int x = 0 ;x <s.size() ;x++) {
			Student stu = s.get(x) ;
			System.out.println(stu.getName() + "---" + stu.getAge());
		}
	}
	
}

class Student {
	 private String name ;
	 private int age ;
	public Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		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;
	}
	
	 
}

Vector集合

 

 

    特点:底层是一种可增长的对象数组,所以查询快增删慢,线程安全,执行效率高。

   public void addElement(Object obj)------->add(Object obj)

   public Enumeration elements():返回此向量的枚举--->相当于:public Iterator iterator()
   boolean hasMoreElements()  --->boolean hasNext() ;
   Object nextElement()    --->Object next() ;

    可以看出Vector集合和ArrayList集合的常用方法的功能效果是一样,只是,Vector集合操作的是元素,遍历时使用的是枚举,例子(没有写Student类):

import java.util.Enumeration;
import java.util.Vector;
public class Test1 {

	public static void main(String[] args) {
		//创建对象
		Vector<Student> v = new Vector<Student>() ;
		Student s1 = new Student("aloha",22) ;
		Student s2 = new Student("alohaa",23) ;
		Student s3 = new Student("alohaaa",24) ;
		//添加元素
		v.addElement(s1);
		v.addElement(s2);
		v.addElement(s3);
		//迭代器遍历
		Enumeration<Student> elements = v.elements();
		while(elements.hasMoreElements()) {
			Student str = elements.nextElement() ;
			System.out.println(str.getName()+"---" + str.getAge());
		}
		System.out.println("------------------------");
		//size()和get(int index)遍历
		for(int x = 0 ;x < v.size() ;x++) {
			Student str = (Student)v.get(x) ;
			System.out.println(str.getName()+"---" + str.getAge());
		}
		
	}

}

LinkedList集合

 

 

    此集合是List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素,包括(null)。

    LinkedList底层是一种链表,所以查询慢,增删块。线程不安全,不同步,所以执行效率高。

 

 

功能:

 添加功能
  addFirst(Object e):将指定的元素插入到列表的开头
  addLast(object e):将指定的元素添加到列表末尾
  获取功能:
  getFirst():获取列表第一个元素
  getLast():获取列表第二个元素
 
  删除功能
  public Object removeFirst()移除并返回此列表的第一个元素。  
  public Object removeLast()移除并返回此列表的最后一个元素。

 

 

例子:

 

import java.util.LinkedList;

public class Test2 {

	public static void main(String[] args) {
		// 创建对象
		LinkedList<Student> ll = new LinkedList<Student>();
		Student s1 = new Student("aloha", 22);
		Student s2 = new Student("alohaa", 23);
		Student s3 = new Student("alohaaa", 24);
		Student s4 = new Student("把你插到首位", 233);
		Student s5 = new Student("把你插到末位", 666);
		Student s6 = new Student("把你插到中间", 555);
		// 添加元素
		ll.add(s1);
		ll.add(s2);
		ll.add(s3);
		// 遍历
		for (Student s : ll) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
		System.out.println("---------------------------");
		// 添加功能
		ll.addFirst(s4);
		ll.addLast(s5);
		ll.add(ll.size() / 2, s6);
		for (Student s : ll) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
		System.out.println("--------------------------");
		// 获取功能
		Student sf = ll.getFirst();
		Student se = ll.getLast();
		System.out.println(
				"获取第一个元素: " + sf.getName() + "---" + sf.getAge() + "\n获取最后一个元素: " + se.getName() + "---" + se.getAge());
		//删除功能
		Student df = ll.removeFirst();
		Student de = ll.removeLast();
		System.out.println(
				"删除并获取第一个元素: " + df.getName() + "---" + df.getAge() + "\n删除并获取最后一个元素: " + de.getName() + "---" + de.getAge());
		System.out.println("-----------------\n删除首尾的结果:");
		for (Student s : ll) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

 

结果:

 

 

    使用LinkedList集合的addFirst() 方法可以模拟我们的堆栈操作,因为这个方法是给集合的第一个元素位置增加元素,而打印的时候也是从第一个元素开始遍历。

集合去重的方式

 

 

    方式一:思想:我们创建两个集合,旧的集合是存放有重复元素的集合,新的集合中存放筛选过后的没有重复的元素。

                 代码如下:

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

/**
 * 集合去重方式一
 * @author malaganguo
 *
 */
public class Test3 {
	
	public static void main(String[] args) {
		
		ArrayList<String> newList = new ArrayList<String>();
		ArrayList<String> oldList = new ArrayList<String>();
		
		oldList.add("nihao") ;
		oldList.add("aloha") ;
		oldList.add("aloha") ;
		oldList.add("hello") ;
		oldList.add("kongnixiwa") ;
		oldList.add("hi") ;
		oldList.add("nihao") ;
		
		//traverse(before)
		System.out.print("before: ");
		for(String s : oldList) {
			System.out.print(s+ " ");
		}
		
		//traverse and add to newList
		Iterator<String> it = oldList.iterator();
		while(it.hasNext()) {
			String str = (String)it.next() ;
			if(!newList.contains(str)) {//如果新集合中不包含的话,执行if的结构体
				newList.add(str);
			}
		}
		//traverse
		System.out.print("\nafter:");
		for(String s : newList) {
			System.out.print(s+ " ");
		}
	}
}

 

    方式二:(不创建新集合)思想:与创建新集合的思想不同,不创建新集合的方法就是给旧集合中的重复元素删除掉,所以我们需要遍历集合并且将所有元素进行比较,如果比较中 发现有相同元素,那么把相同元素的重复元素删除掉。

    代码如下:

 

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

/**
 * 集合去重: 方式二
 * @author malaganguo
 *
 */
public class Test4 {
	
	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<String>() ;
		
		list.add("nihao") ;
		list.add("aloha") ;
		list.add("aloha") ;
		list.add("hello") ;
		list.add("kongnixiwa") ;
		list.add("hi") ;
		list.add("nihao") ;
		//traverse&delete before
		System.out.print("traverse&delete before: ");
		for(String s :list) {
			System.out.print(s+ " ");
		}
		/**
		 * Exception in thread "main"
		 * checkForComodification
		 */
//		for(String s1 : list) {
//			if(list.contains(s1)) {
//				list.remove(s1);
//			}
//		}
		//delete repet
		for(int x = 0 ;x <list.size()-1;x++) {
			for(int y = x+1 ; y < list.size() ; y++) {
				if(list.get(x).equals(list.get(y))) {
					list.remove(y) ;
				}
			}
		}
		//traverse&delete after
		System.out.print("\ntraverse&delete after:  ");
		for(String s :list) {
			System.out.print(s+ " ");
		}
	}
}

 

对于对象集合的去重,我们需要比较对象元素是否相同,这个比较和字符串集合比较不同的是,字符串类型重写了equals方法,所以可以直接比较字符串是否相同,但是我们创建的对象集合中并没有重写这个方法,比较的还是地址值,所以无法比较出内容是否相同,需要我们重写euqals方法。

例子:

 

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

/**
 * 需求:使用集合ArrayList存储自定义对象(StudentWithOverride),去除重复的对象(成员变量的值一样,看成一个人)
 * @author malaganguo
 * 
 * 
 * 结果:没有完成需求,并没有在新集合中添加不重复的元素
 * 原因:String类中默认重写了equals方法,比较的是数值,而我们自己创建的类中默认equals方法比较的是地址值,所以没有办法完成去重
 */
public class Test5 {
	
	public static void main(String[] args) {
		//创建对象
		ArrayList<StudentWithOverride> s =  new ArrayList<StudentWithOverride>() ;
		StudentWithOverride s1 = new StudentWithOverride("aloha", 22);
		StudentWithOverride s2 = new StudentWithOverride("alohaa", 23);
		StudentWithOverride s3 = new StudentWithOverride("alohaaa", 24);
		StudentWithOverride s4 = new StudentWithOverride("我是重复的", 233);
		StudentWithOverride s5 = new StudentWithOverride("我是重复的", 233);
		StudentWithOverride s6 = new StudentWithOverride("aloha", 22);
		//将对象元素加入集合
		s.add(s1);
		s.add(s2);
		s.add(s3);
		s.add(s4);
		s.add(s5);
		s.add(s6);
		
		
		//去除重复对象
		/**
		 * 不知道为啥这个就是没有办法去重
		 */
		//方法一:
//		for(int x = 0 ;x < s.size()-1 ;x++) {
//			for(int y =x+1 ;y <s.size();y++) {
//				if(s.get(x).equals(s.get(y))) {
//					s.remove(y) ;
//				}
//			}
//		}
	
		//方法二:创建一个新集合,用迭代器去重
		ArrayList<StudentWithOverride> newList = new ArrayList<StudentWithOverride>();
		Iterator<StudentWithOverride> it = s.iterator();
		while(it.hasNext()) {
			StudentWithOverride stu = it.next();
			if(!newList.contains(stu)) {
				newList.add(stu) ;
			}
		}
		//遍历
		Iterator<StudentWithOverride> it2 = newList.iterator();
		while(it2.hasNext()) {
			StudentWithOverride ss = it2.next() ;
			System.out.println(ss.getName()+ "---"+ ss.getAge());
		}
		
	}

}

class StudentWithOverride{
	private String name ;
	private int age ;
	public StudentWithOverride() {
		super();
	}
	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;
	}
	public StudentWithOverride(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override //为什么字符串去重没有问题,而我们自己定义的类对象就没有办法去重呢?因为String类型默认重写了equals方法。
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		StudentWithOverride other = (StudentWithOverride) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
	
}

 

这样就可以实现非String类型的对象去重了!

针对数组操作的工具类:Arrays,提供了一个方法:
  public static <T> List<T> asList(T... a) :将数组转换成固定大小的集合

 

import java.util.List;
import java.util.Arrays;

/**
 * Arrays提供的从数组转变成集合的方法:
 * public static <T> List<T> asList(T... a) :将数组转换成固定大小的集合
 * 缺点:集合的长度固定,不能再改变了
 * @author malaganguo
 *
 */
public class Test5 {

	public static void main(String[] args) {
		
		//将字符串数组转换位String类型的List集合
		List<String> list = Arrays.asList("hello","world","java","!") ;
		
//		list.add("javaee");//会报错java.lang.UnsupportedOperationException
//		list.remove("hello") ;//会报错java.lang.UnsupportedOperationException
		list.set(0, "nihao");
		for(String str : list) {
			System.out.println(str);
		}
		/**输出结果:
		 *  nihao
	     *	world
		 *	java
		 *	!
		 */
	}
}

 

泛型

 

 

 

    当我们需要给对象中存储元素时,由于集合中只能存储相同类型的元素,假如我们在集合中存储了String 类型的元素和int类型的元素,那么我们在编译的时候时没有问题的,但是在运行的时候就会报错,为了防止出现其他类型的元素通过了编译,我们   引入了泛型,泛型可以规定我们集合的存储类型。用法<这里是引用数据类型>,将明确集合类型的工作推迟到了创建对象或者调用方法的时候,属于一种参数化类型,可作为参数传递。

    泛型的好处:

 

 

        (1)解决了黄色警告线问题!

        (2)将运行时期的异常提前到了编译时期!

        (3)避免了强制类型转换!

    可见,泛型提高了程序的安全性。

 

将泛型定义在类上,成员位置上

 

 

      我们在创建一个类的时候,可以将泛型定义在这个类上,这样,我们就规定了类中的成员的类型,我们在创建这个类的对象的时候只需要知名这个类的泛型,那么,在我们下面使用对象做事情的时候就会出现类型锁定的情况,即只能使用我们泛型中规定的类型。

例子:

/**
 * 将泛型定义在类上
 * @author malaganguo
 *
 */

class Student<T>{
	private T name ;

	public T getName() {
		return name;
	}

	public void setName(T name) {
		this.name = name;
	}
	public T print(T a ,T b) {
		T c = b ;
		return c;
	}
}
public class Test1 {

	public static void main(String[] args) {
		Student<String> stu = new Student<String>() ;
		stu.setName("aloha");
		System.out.println(stu.print("haha", "233"));
		System.out.println(stu.getName());
	}
}

泛型高级——通配符

 

 

    <?>代表任意类型,如Object类型或者java类

    <? extends E> 向下限定E的子类或者E这个类型

 

 

    <? super E>向上限定,E类型以及其父类

集合的嵌套遍历

 

 

    即大集合中包含小集合,那么大集合的泛型位集合类型,小集合的类型为我们定义的类型。嵌套集合的思想:首先创建一个大集合和n个小集合,给每个小集合中添加元素,然后将各个小集合添加到大集合中,这就完成了集合的嵌套。关于集合的嵌套遍历,我们使用增强for循环(传送门:https://blog.csdn.net/weixin_38930706/article/details/80250301)的嵌套:我们的第一层增强for循环用来遍历小集合,将遍历的小集合传给一个新集合对象,然后第二层增强for循环遍历第一层中的新集合对象,将元素便利出来,输出打印。

    代码:(部分)

import java.util.ArrayList;

/**
 * 集合的嵌套遍历
 * @author malaganguo
 *
 */
public class Test1 {

	public static void main(String[] args) {
		
		//创建一个大集合,这个集合中存放着小集合,那么大集合的泛型是一个集合类型
		ArrayList<ArrayList<Student>> bigArrayList = new ArrayList<ArrayList<Student>>() ;
		//创建两个小集合
		ArrayList<Student> arrayList1 = new ArrayList<Student>() ;
		ArrayList<Student> arrayList2 = new ArrayList<Student>();
		//创建四个学生对象
		Student s1 = new Student("你好", 22);
		Student s2 = new Student("ALOHA", 23);
		Student s3 = new Student("hello", 24);
		Student s4 = new Student("nihao", 25);
		//将创建的对象加入集合中
		arrayList1.add(s1);
		arrayList1.add(s2);
		arrayList2.add(s3);
		arrayList2.add(s4);
		//将两个小集合加入到大集合中
		bigArrayList.add(arrayList1);
		bigArrayList.add(arrayList2);
		//遍历
		for(ArrayList<Student> al : bigArrayList) {
			for(Student stu1 : al) {
				System.out.println(stu1.getName()+ "---" + stu1.getAge());
			}
		}
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值