在list中有一个特殊的迭代器,其他的集合都没有只是list有叫做ListIterater 这个迭代器比一般的迭代器会多非常多的功能 另外注意的一点就是在使用iterater进行list迭代的时候,不能够使用集合的方法对集合进行增删改查的操作 否则就会出现一个运行时异常,主要原因就是同时操作一个集合导致不合法,类似于同时IO同一块数据块 因此在迭代的过程中只能使用迭代器提供的操作集合的方法 或者不使用迭代器,直接使用原生的for循环,然后直接就可以使用迭代器的方法进行对集合的操作
public class Enmu {
public static void main(String[] args) {
Vector v=new Vector();
v.add("1");
v.add("2");
v.add("3");
Enumeration e=v.elements(); //定义枚举
while (e.hasMoreElements()){ //循环遍历
System.out.println(e.nextElement());
}
}
}
代码如下:
public class LinkedList_5 {
public static void main(String[] args) {
LinkedList list=new LinkedList();
list.addFirst("1");
list.addFirst("2");
list.addFirst("3");
System.out.println(list.getFirst());
System.out.println(list.removeFirst());
LinkedList list1=new LinkedList();
list1.offerFirst("1");
list1.offerFirst("2");
list1.offerFirst("3");
System.out.println(list1.peekFirst());
System.out.println(list1.pollFirst());
}
}
7.使用LinkedList实现堆栈和队列结构也就是他所特有的addFirst addLast 以及remove方法的使用 只是要注意在LinkedList里面添加和删除的元素都是object而不是一般的对象,应该说 所有的集合框架里面的东西都是接受object对象的 所以在写具体的函数的时候注意一下
8.使用ArrayList写几个小程序,第一个就是使用ArrayList去处重复元素,其中的元素就是字符串,而第二个则是 去除的某些自定义对象。第二个程序也揭示了对于List集合中的元素的比较的接口就是contains他底层是调用 的对象的equals方法,对于remove也是底层调用了equals方法从而进行比较和删除。所以说重点在于重写 equals方法。 另外在迭代器中每使用一次next方法必须要进行一次hasNext的判断否则很有可能出现找不到元素的情况 例如一个hasNext里面有两个next方法,而元素又为奇数个时候会抛异常
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
String getName(){
return this.name;
}
private int getAge(){
return this.age;
}
public boolean equals(Object object){
if (!(object instanceof Person)){
return false;
}
Person person=(Person)object; //注意这个地方必须要强转否则会出现下面的person无法调用方法
return this.name.equals(person.getName()) && this.age==person.getAge();
}
}
public class ArrayList_7 {
private static ArrayList<Person> singleElement(List<Person> al){
ArrayList<Person> newAl=new ArrayList<Person>();
Iterator<Person> it=al.iterator();
while (it.hasNext()){
Person tmp= it.next(); //iterator返回的是object所以必须要强转
if (!newAl.contains(tmp)){
newAl.add(tmp);
}
}
return newAl;
}
public static void main(String[] args) {
ArrayList<Person> al=new ArrayList<>();
al.add(new Person("zhang01",1));
al.add(new Person("zhang02",2));
al.add(new Person("zhang03",1));
al.add(new Person("zhang03",1));
al=singleElement(al);
for (Person per : al) { //可以使用这种更好的语言结构来实现迭代省去了iterator迭代 也不用考虑向下类型转换
System.out.println(per.getName());
}
}
}
9.Set中存放的元素都是无序的并且里面的元素都是不可重复的,显然如果只存放字符串的话很容易就知道是否重复 也就无序我们自己去判断是否重复了。 set中的公共方法就是集合框架中共有的方法,重要的还是他的子类,这里有两个就是hashSet和TreeSet
而存放一般的自定义对象的时候我们发现如果想要某些属性一致的对象作为重复对象 的话hashSet自身是做不到的,所以我们需要了解hashSet的底层层放原理,hashSet底层就是hash表,在存放元素的时候 首先来判断存放的元素的hashCode值是否一样也就是调用他们的hashCode方法,注意hashCode是object对象的方法,所以 所有的对象都有此方法,另外如果他们的hashCode是一样的然后就调用他们的equals方法.不一样则就存进去一样则被踢出去 那么说白了hashSet底层判断是否为重复元素做了两件事第一个就是判断他们的hashCode第二个就是equals方法 如果要自定义对象如何存放就要重写这两个方法,但是重写的时候一定要注意他们的参数列表否则肯定不会生效,hashCode 一般来说也尽量不要让不同的对象的hashCode一致造成多余的比较
对于元素判断是否存在和删除元素都是hashCode和equals方法
下面是hashSet的代码示例:
class People{
private String name;
private int age;
People(String name,int age){
this.name=name;
this.age=age;
}
String getName(){
return this.name;
}
private int getAge(){
return this.age;
}
public int hashCode(){
return name.hashCode()+age;
}
public boolean equals(Object object){
if (!(object instanceof People)){
return false;
}
People person=(People)object; //注意这个地方必须要强转否则会出现下面的person无法调用方法
return this.name.equals(person.getName()) && this.age==person.getAge();
}
}
public class HashSet_8 {
public static void main(String[] args) {
HashSet<People> hs=new HashSet<People>();
hs.add(new People("1",11));
hs.add(new People("2",11));
hs.add(new People("1",11));
for (People pe:hs){
System.out.println(pe.getName());
}
}
}
10.treeSet是在集合中的元素会自动排序,如果是字符串什么的他们都可以自动比较,因为字符串是已经实现了Compareable接口 但是如果要存放一般的元素对象的时候注意一定要让改类实现compareable接口,因为此接口会让类强制具有比较性 然后复写此接口中的compareTo方法,大于返回正数等于为零小于则为负,这里要注意如果有多个排序元素的话然后在比较 的时候相等条件判断要注意对其他排序元素的判断,否则会造成某个条件相等但是并不是同一个元素而无法存入
class Student implements Comparable{
private String name;
private int age;
Student(String name,int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Object o) {
if (!(o instanceof Student)){
throw new RuntimeException("not same type");
}
if (this.age>((Student) o).age){
return 1;
}else if (this.age==((Student) o).age){
return this.name.compareTo(((Student) o).name);
//注意多重判断,要是age一样的话他们就会被当成相同元素而无法插入 string类已经实现了comparable接口
//其实java中很多类都实现了comparable接口,让类具有可比性
}
return -1;
}
}
public class TreeSet_9 {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<>();
ts.add(new Student("ab",1));
ts.add(new Student("kb",3));
ts.add(new Student("mb",3));
ts.add(new Student("am",7));
for (Student stu :
ts) {
System.out.println(stu.getName()+"--------"+stu.getAge());
}
}
}
11.TreeSet底层的数据结构就是二叉树,元素的排列方式就是第一个进入的元素作为根节点然后按照compareTo方法 返回的值来判定是左孩子还是右孩子,这里就是如果说compareTo方法返回的正数则右孩子,负数为左孩子相等就说明 是同一个元素不用再比较。 所以说决定了TreeSet中的元素的重复与否就是compareTo函数的返回值 那么这样的话我们也可以规定一个TreeSet按照放进去的顺序取出来 或者倒序取出来就是compareTo全部返回1 或者-1即可,当然如果返回的始终为0那么最后集合中只有一个元素就是第一个元素
12.在TreeSet中除了实现comparable接口复写compareTo方法以外还有一种排序方法就是比较器,前面的comparable 接口是让元素具有了比较性而比较器则是让集合具有了比较性这个优先级跟高,具体的方法就是在集合实例化的时候传入一个 自定义的比较器,也就是构造方法传入一个比较器对象,这个比较器也是一个接口要实例化的话需要实现他的compare方法 比较器也是更加常用的
class MyComparator implements Comparator{
public int compare(Object o1,Object o2){
Student obj1=(Student)o1;
Student obj2=(Student)o2;
int num=obj1.getName().compareTo(obj2.getName());
if (num==0){
return new Integer(obj1.getAge()).compareTo(obj2.getAge());
}
return num;
}
}
public class TreeSet_10 {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());
ts.add(new Student("dsf",11));
ts.add(new Student("dmf",12));
ts.add(new Student("ddf",13));
ts.add(new Student("jf",14));
for (Student stu :
ts) {
System.out.println(stu.getName()+"----------"+stu.getAge());
}
}
}