java基础笔记(8)ArrayList,List,hashcode和equals方法

ArrayList集合
初始数组长度是10, 可以自动扩容

  1. 产生副本 遍历的是副本
  2. 遍历副本的时候, 修改的是源集合, 删除副本的元素
  3. 将副本替换掉原集合
public class Test {
    
    
	public static void main(String[] args) {
    
    
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		for (String string : list) {
    
    
			if(string instanceof String) {
    
    
				list.remove(string);
			}
		}
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
    
    
			String obj = it.next();
			if(obj instanceof String) {
    
    
				it.remove();
			}		
		}		
		// 遍历的就是原集合,不是副本
		for (int i = 0; i < list.size(); i++) {
    
    
			String str = list.get(i);
			if(str instanceof String) {
    
    
				list.remove(str);
				// 产生过删除操作的位置,则 i--, 重新检查一遍
				i--;
			}
		}
		System.out.println(list);
	}
}

List : 有序并且允许重复
LinkedList : 有序并且允许重复
底层数据结构是双向链表 堆栈结构
优点: 插入和删除的时候 效率高
缺点: 遍历和修改的时候 效率低

public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		//创建LinkerList集合对象
		LinkedList<String> list = new LinkedList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		//头和尾的操作
		list.addFirst("z");
		list.addLast("y");
		System.out.println(list);		
		String first = list.getFirst();
		String last = list.getLast();
		System.out.println(first);
		System.out.println(last);	
		list.offerFirst("z");
		list.offerLast("y");
		System.out.println(list);
		String peekFirst = list.peekFirst();
		String peekLast = list.peekLast();
		System.out.println(peekFirst);
		System.out.println(peekLast);		
		System.out.println(last);		
		// 获取集合开头和结尾的元素,并且在集合中移除
		String pollFirst = list.pollFirst();
		String pollLast = list.pollLast();
		System.out.println(list);		
		//弹栈
		String pop = list.pop();
		System.out.println(pop);
		System.out.println(list);		
		//压栈
		list.push("z");
		System.out.println(list);		
		list.add("a");
		list.remove("a");
		list.removeFirst();
		list.removeLast();		
		//遍历
		for (String string : list) {
    
    
			System.out.println(string);
		}		
		for (int i = 0; i < list.size(); i++) {
    
    
			System.out.println(list.get(i));
		}		
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
    
    
			iterator.next();			
		}		
		Object[] obj = list.toArray();		
		// 要求向集合中添加10个不重复的10~20之间的随机数
		LinkedList<Integer> list2 = new LinkedList<>();
		for (int i = 0; i < 10; i++) {
    
    
			int num = (int)(Math.random()*(20-10+1)+10);
			if(!list2.contains(num)) {
    
    
				list2.add(num);
			}else {
    
    
				i--;
			}
		}
		System.out.println(list2);
	}
}

ArrayList 线程不安全的 效率高
Vector 线程安全的 效率低

public class Test3 {
    
    
	public static void main(String[] args) {
    
    
		ArrayList<Integer> list = new ArrayList<>();
		list.add(3);		
		// 可以有顺序的  迭代器    指针默认在 所有元素的前面
		ListIterator<Integer> listIterator = list.listIterator();
		// 将指针放到  下标为1的元素位置
		ListIterator<Integer> listIterator2 = list.listIterator(1);		
		while (listIterator2.hasPrevious()) {
    
    
			Integer num = listIterator2.previous();
			if(num==3) {
    
    
				//在遍历过程中添加元素
				listIterator2.add(6);
			}
		}
		System.out.println(list);
	}
}

hashcode和equals方法
属性值相同则认为是同一个对象 则不添加到集合 , 需要重写hashcode和equals方法
内容相同, 属性 name age 进行计算哈希吗 , 是跟属性相关 跟对象的内存地址无关
默认情况: 根据对象的内存地址,进行一定运算得到的int类型数据
当hashcode方法得到的哈希值 是表中存在的, 则调用equals方法, 让equals进行判断 各个属性是否相同
默认情况是 内存地址不同就存储多分
1.先调用hashcode
2. 如果hashcode不同, 则直接添加到集合
3. 如果hashcode相同. 则调用equals ,
4. equals’结果是true, 不加, equals 结果为false 加

public class Person {
    
    
	String name;
	int age;
	String gender;
	String hobby;
	public Person(String name, int age, String gender, String hobby) {
    
    
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.hobby = hobby;
	}
	@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
	public boolean equals(Object obj) {
    
    
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) 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;
	}
}
public class Student {
    
    
	String name;
	int age;
	public Student() {
    
    
		super();
		
	}
	public Student(String name, int age) {
    
    
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
    
    
		return "Student [name=" + name + ", age=" + age + "]";
	}
	// 重写hashcode 
		@Override
		public int hashCode() {
    
    			System.out.println("======hashCode===");
			// 内容相同, 属性 name  age 进行计算哈希吗 , 是跟属性相关 跟对象的内存地址无关
			int result = 0;
			result+=age;
			result+=name.hashCode();
			// 默认情况: 根据对象的内存地址,进行一定运算得到的int类型数据
			return result;
		}		
		// 当hashcode方法得到的哈希值 是表中存在的, 则调用equals方法, 让equals进行判断 各个属性是否相同		
		@Override
		public boolean equals(Object obj) {
    
    
			System.out.println("======equals===");
			// 重写equals
			if(obj instanceof Student){
    
    
				Student stu = (Student) obj;
				if(this.age == stu.age){
    
    
					if(this.name.equals(stu.name)){
    
    
						return true;
					}
				}
			}
			return false;
		}
}
public class Test {
    
    
	public static void main(String[] args) {
    
    
		HashSet<String> set = new HashSet<>();
		set.add("zzz");
		set.add("aaa");
		set.add("bbb");
		set.add("zzz");
		System.out.println(set);
		HashSet<Integer> set2 = new HashSet<>();
		set2.add(7);
		set2.add(8);
		set2.add(1);
		set2.add(1);
		System.out.println(set2);
		// 默认情况是 内存地址不同就存储多分
		// 需求: 内存地址, 内容相同 都只存储一份
		HashSet<Student> set3 = new HashSet<>();
		Student stu = new Student("张三",2);
		set3.add(stu);
		set3.add(new Student("李四",18));
		set3.add(new Student("王五",18));
		set3.add(new Student("赵六",18));
		set3.add(new Student("赵六",18));
		System.out.println(set3);
	}
	public static void add(Student stu) {
    
    
		// 1. 先调用对象的hashcode方法的到一个哈希值
		int hashCode = stu.hashCode();
		//2. 去哈希表中查找遍历, 是否有相同的哈希值
				//3. 找到相同的了哈希值,但是哈希值相同不一定是相同的对象
				//4. 则调用equals方法 进行 判断 每个属性是否相同,
				//5. 如果各个属性都相同, 就是相同对象,则不添加
				//    如果属性不同,则认为是不同的对象, 就添加
				// equals
	}
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		HashSet<Person> set = new HashSet<>();
		set.add(new Person("a", 5, "男", "玩"));
		set.add(new Person("a", 5, "男", "玩"));
		System.out.println(set);		
		//集合的嵌套
		HashSet<ArrayList<String>> set2 = new HashSet<>();		
		ArrayList<String> list = new ArrayList<>();
		list.add("a");
		list.add("a");
		list.add("a");		
		set2.add(list);
		ArrayList<String> list2 = new ArrayList<>();
		list2.add("b");
		list2.add("b");
		list2.add("b");
		set2.add(list2);		
		//遍历集合
		for (ArrayList<String> lists : set2) {
    
    
			for (String string : list2) {
    
    
				System.out.println(string);
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Echoxxxxx/article/details/112447064