List集合介绍及常用方法
import java.util.ArrayList; import java.util.Iterator; import java.util.List; /* java.util.List接口 extends Collection接口 List接口的特点: 1.有序的集合,存储元素和取出元素的顺序是一致的(存储123 取出123) 2.有索引,包含了一些带索引的方法 3.允许存储重复的元素 List接口中带索引的方法(特有) -public void add(int index, E element):将指定的元素,添加到该集合中的指定位置上 -public E get(int index):返回集合中指定位置的元素 -public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素 -public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前元素 注意: 操作索引的时候,一定要防止索引越界异常 IndexOutOfBoundsException:索引越界异常,集合会报 ArrayIndexOutOfBoundsException:数组索引越界异常 StringIndexOutOfBoundsException:字符串索引越界异常 */ public class Demo01List { public static void main(String[] args) { //创建一个List集合对象,多态 List<String> list = new ArrayList<>(); //使用add方法往集合中添加元素 list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("a"); //打印集合 System.out.println(list);//[a, b, c, d, a] 不是地址重写了toString方法 //public void add(int index, E element):将指定的元素,添加到该集合中的指定位置上 //在c和d之间添加一个itheima list.add(3,"itheima"); System.out.println(list); //public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素 //移除元素 String removeE = list.remove(2); System.out.println("被移除的元素:"+removeE);//被移除的元素:c System.out.println(list);//[a, b, itheima, d, a] //public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前元素 //把最后一个a,替换为A String setE = list.set(4,"A"); System.out.println("被替换的元素:"+setE);//被替换的元素:a System.out.println(list);//[a, b, itheima, d, A] //List集合遍历有3种方式 //使用普通的for循环 for (int i = 0; i < list.size(); i++) { //public E get(int index):返回集合中指定位置的元素 String s = list.get(i); System.out.println(s); } System.out.println("=============================================="); //使用迭代器 Iterator<String> it = list.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s); } System.out.println("==============================================="); //使用增强for for (String s : list) { System.out.println(s); } String r = list.get(5); System.out.println(r);//IndexOutOfBoundsException } }
ArrayList集合
java.util.ArrayList集合,数据存储的结构是数组结构。元素查询快,增删慢,由于日常开发中使用最多的功能为查询数据,遍历数据,所以ArrayList是最常用的集合
LinkedList集合
import java.util.LinkedList; /* java.util.LinkedList集合 implements List接口 LinkedList集合的特点: 1.底层是一个链表结构:查询慢,增删快 2.里边包含了大量操作首尾元素的方法 注意:使用LinkedList集合特有的方法,不能使用多态 - public void addFirst(E e):将指定元素插入此列表的开头 - public void addLast(E e):将指定元素添加到此列表的结尾 - public void push(E e):将元素推入此列表所表示的堆栈 - public E getFirst():返回此列表的第一个元素 - public E getLast():返回此列表的最后一个元素 - public E removeFirst():移除并返回此列表的第一个元素 - public E removeLast():移除并返回此列表的最后一个元素 - public E pop():从此列表所表示的堆栈处弹出一个元素 - public boolean isEmpty():如果列表不包含元素,则返回true */ public class Demo02LinkedList { public static void main(String[] args) { show01(); show02(); show03(); } /* - public E removeFirst():移除并返回此列表的第一个元素 - public E removeLast():移除并返回此列表的最后一个元素 - public E pop():从此列表所表示的堆栈处弹出一个元素。此方法相当于removeFirst() */ private static void show03() { //创建LinkedList集合对象 LinkedList<String> linked = new LinkedList<>(); //使用add方法往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c"); System.out.println(linked); //String first = linked.removeFirst(); String first = linked.pop(); System.out.println("被移除的第一个元素:"+first); String last = linked.removeLast(); System.out.println("被移除的最后一个元素:"+last); System.out.println(linked);//[b] } /* - public E getFirst():返回此列表的第一个元素 - public E getLast():返回此列表的最后一个元素 */ private static void show02() { //创建LinkedList集合对象 LinkedList<String> linked = new LinkedList<>(); //使用add方法往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c"); //linked.clear();//清空集合中的元素 再获取集合中的元素会抛出NoSuchElementException //public boolean isEmpty():如果列表不包含元素,则返回true if (!linked.isEmpty()){ String first = linked.getFirst(); System.out.println(first);//a String last = linked.getLast(); System.out.println(last);//c } } /* - public void addFirst(E e):将指定元素插入此列表的开头 - public void addLast(E e):将指定元素添加到此列表的结尾 - public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于addFirst(E)。 */ private static void show01() { //创建LinkedList集合对象 LinkedList<String> linked = new LinkedList<>(); //使用add方法往集合中添加元素 linked.add("a"); linked.add("b"); linked.add("c"); System.out.println(linked);//[a, b, c] //public void addFirst(E e):将指定元素插入此列表的开头 //linked.addFirst("www"); linked.push("www");//[www, a, b, c] System.out.println(linked);//[www, a, b, c] //public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于add() linked.addLast("com"); System.out.println(linked);//[www, a, b, c, com] } }
Vector集合
与ArrayList集合类似,底层是数组,但是是单线程同步的,速度要慢
HashSet
HashSet集合介绍
import java.util.HashSet; import java.util.Iterator; import java.util.Set; /* java.util.Set接口 extends Collection接口 Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.util.HashSet集合 implements Set接口 HashSet特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致 4.底层是一个哈希表结构(查询速度非常快) */ public class Demo01Set { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); //使用add方法往集合中添加元素 set.add(1); set.add(3); set.add(2); set.add(1); //使用迭代器遍历set集合 Iterator<Integer> it = set.iterator(); while (it.hasNext()){ Integer n = it.next(); System.out.println(n);//1,2,3 } //使用增强for遍历set集合 System.out.println("======================================"); for (Integer i : set) { System.out.println(i);//1,2,3 } } }
哈希值
public class Person extends Object{ //重写hashCode方法 @Override public int hashCode() { return 1; } } ====================================================== /* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址) 在Object类有一个方法,可以获取对象的哈希值 int hashCode() 返回该对象的哈希码值 hashCode方法的源码: public native int hashCode(); native:代表该方法调用的是本地操作系统的方法 */ public class Demo01HashCode { public static void main(String[] args) { //Person类继承了Object类,所以可以使用Object类的hashCode方法 Person p1 = new Person(); int h1 = p1.hashCode(); System.out.println(h1);//460141958 |1 Person p2 = new Person(); int h2 = p2.hashCode(); System.out.println(h2);//1163157884 |1 /* toString方法的源码: return getClass().getName() + "@" + Integer.toHexString(hashCode()); */ System.out.println(p1);//com.collection.demo03_hashCode.Person@1b6d3586 System.out.println(p2);//com.collection.demo03_hashCode.Person@4554617c System.out.println(p1==p2);//false /* String类的哈希值 String类重写了Object类的hashCode方法 */ String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.hashCode());//96354 System.out.println(s2.hashCode());//96354 System.out.println("重地".hashCode());//1179395 System.out.println("通话".hashCode());//1179395 } }
HashSet集合存储数据的结构
Set集合存储元素不重复的原理
HashSet存储自定义类型元素
import java.util.HashSet; /* HashSet存储自定义类型元素 Set集合保证元素唯一: 存储的元素(String,Integer,...Student,Person...),必须重写hashCode方法和equals方法 要求: 同名同年龄的人,视为同一个人,只能存储一次 */ public class Demo03HashSetSavePerson { public static void main(String[] args) { //创建HashSet集合存储Person HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小美女",18); Person p2 = new Person("小美女",18); Person p3 = new Person("小美女",19); System.out.println(p1.hashCode());//460141958 System.out.println(p2.hashCode());//1163157884 System.out.println(p1==p2);//false System.out.println(p1.equals(p2));//false set.add(p1); set.add(p2); set.add(p3); System.out.println(set); } } ========================================================= import java.util.Objects; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", 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; } }
LinkedHashSet集合
import java.util.HashSet; import java.util.LinkedHashSet; /* java.util.LinkedHashSet集合 extends HashSet集合 LinkedHashSet集合特点: 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序 */ public class Demo04LinkedHashSet { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); set.add("www"); set.add("abc"); set.add("abc"); set.add("itcast"); System.out.println(set);//[abc, www, itcast]无序,不允许重复 LinkedHashSet<String> linked = new LinkedHashSet<>(); linked.add("www"); linked.add("abc"); linked.add("abc"); linked.add("itcast"); System.out.println(linked);//[www, abc, itcast]有序,不允许重复 } }
可变参数
/* 可变参数:是JDK1.5之后出现的新特性 使用前提: 当方法的参数列表数据类型已经确定但是参数的个数不确定,就可以使用可变参数 使用格式:定义方法时使用 修饰符 返回值类型 方法名(数据类型...变量名){} 可变参数的原理: 可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数 传递的参数个数,可以是0个(不传递),1,2...多个 */ public class Demo01VarArgs { public static void main(String[] args) { //int i = add(); //int i = add(10); int i = add(10,20); //int i = add(10,20,30,40,50,60,70,80,90,100); System.out.println(i); method("abc",5.5,10,1,2,3,4); } /* 可变参数的注意事项 1.一个方法的参数列表,只能有一个可变参数 2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾 */ /*public static void method(int...a,String...b){ }*/ /*public static void method(String b,double c,int d,int...a){ }*/ //可变参数的特殊(终极)写法 public static void method(Object...obj){ } /* 定义计算(0-n)整数和的方法 已知:计算整数的和,数据类型已经确定int 但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数 add();就会创建一个长度为0的数组,new int[0] add(10);就会创建一个长度为1的数组,存储传递过来的参数,new int[]{10}; add(10,20);就会创建一个长度为2的数组,存储传递过来的参数,new int[]{10,20}; add(10,20,20,40,50,60,70,80,90,100);就会创建一个长度为10的数组,存储传递过来的参数,new int[]{10,20,20,40,50,60,70,80,90,100}; */ public static int add(int...arr){ //System.out.println(arr);//[I@1b6d3586 int类型数组的地址,底层是一个数组 //System.out.println(arr.length);//0,1,2,10 //定义一个初始化的变量,记录累加求和 int sum = 0; //遍历数组,获取数组中的每一个元素 for (int i : arr) { //累加求和 sum += i; } //return 0; //把求和返回 return sum; } //定义一个方法,计算三个int类型整数的和 //public static int add(int a,int b,int c){ // return a+b+c; //} //定义一个方法,计算两个int类型整数的和 //public static int add(int a,int b){ // return a+b; //} }