16.01 ArrayList存储字符串并遍历
ArrayList类概述:底层数据结构是数组,查询快,增删慢,线程不安全,效率高
ArrayList类是List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al = new ArrayList(); 6 al.add("hello"); 7 al.add("world"); 8 al.add("java"); 9 10 Iterator it = al.iterator();11 while(it.hasNext())12 {13 String s = (String)it.next();14 System.out.println(s);15 }16 }17 }
16.02 ArrayList存储自定义对象并遍历
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al = new ArrayList(); 6 al.add(new Student("小明",23)); 7 al.add(new Student("小红",15)); 8 al.add(new Student("旺财",16)); 9 al.add(new Student("小强",21));10 al.add(new Student("张三",23));11 12 Iterator it = al.iterator();13 while(it.hasNext())14 {15 Student s = (Student)it.next();16 System.out.println(s.getName()+":"+s.getAge());17 }18 }19 }
16.03 Vector的特有功能
Vector类概述:底层数据结构是数组,查询快,增删慢,线程安全,效率低
Vector类特有功能
1. public void addElement( obj):
将指定的组件添加到此向量的末尾,将其大小增加 1。 该方法被add()替代
2. public elementAt(int index):
返回指定索引处的组件。 该方法被get()替代
3. public <> elements():
返回此向量的组件的枚举。 该方法被Iterator iterator()替代
补充知识:JDK升级的原因,安全、效率、简化书写
16.04 LinkedList的特有功能
LinkedList类概述:底层数据结构是链表,查询慢,增删快,线程不安全,效率高
LinkedList类特有功能
1. public void addFirst( e):将指定元素插入此列表的开头。
2. public void addLast( e):将指定元素添加到此列表的结尾。
3. public getFirst():返回此列表的第一个元素。
4. public getLast():返回此列表的最后一个元素。
5. public removeFirst():移除并返回此列表的第一个元素。
6. public removeLast():移除并返回此列表的最后一个元素。
16.05 去除ArrayList集合中的重复字符串元素案例1(两个集合)
去除ArrayList集合中字符串的重复值(字符串的内容相同)
思路:创建两个集合,遍历旧集合获取每一个元素,查看遍历到的元素在新集合中是否存在,存在不操作,不存在存入新集合
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al = new ArrayList(); 6 7 al.add("java"); 8 al.add("hello"); 9 al.add("java");10 al.add("world");11 al.add("hello");12 al.add("java");13 //创建新集合14 ArrayList newArray = new ArrayList();15 16 Iterator it = al.iterator();17 while(it.hasNext())18 {19 String s = (String)it.next();20 if(!newArray.contains(s))21 newArray.add(s);22 }23 //遍历新集合24 Iterator newit = newArray.iterator();25 while(newit.hasNext())26 {27 String s = (String)newit.next();28 System.out.println(s);29 }30 }31 }
16.06 去除ArrayList集合中的重复字符串元素案例2(单个集合)
去除ArrayList集合中字符串的重复值(字符串的内容相同),要求不能创建新集合
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al = new ArrayList(); 6 7 al.add("java"); 8 al.add("hello"); 9 al.add("java");10 al.add("world");11 al.add("world");12 al.add("world");13 al.add("hello");14 al.add("java");15 16 for (int i = 0; i < al.size()-1; i++) 17 {18 for (int j = i + 1; j < al.size(); j++) 19 {20 if(al.get(i).equals(al.get(j)))21 {22 al.remove(j); 23 j--;24 }25 }26 }27 28 Iterator it = al.iterator();29 while(it.hasNext())30 {31 String s = (String)it.next();32 System.out.println(s);33 }34 }35 }
16.07 去除ArrayList集合中的重复自定义对象元素案例
去除ArrayList集合中自定义对象的重复值(对象的成员变量值都相同)
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al1 = new ArrayList(); 6 7 al1.add(new Student("小明",23)); 8 al1.add(new Student("小明",23)); 9 al1.add(new Student("小红",15));10 al1.add(new Student("旺财",16));11 al1.add(new Student("小明",18));12 al1.add(new Student("旺财",16));13 al1.add(new Student("小强",21));14 15 ArrayList al2 = new ArrayList();16 //遍历旧集合17 Iterator it = al1.iterator();18 while(it.hasNext())19 {20 Student s = (Student)it.next();21 //contains()方法底层依赖的是equals()方法22 //Object的equals()方法默认比较的是地址值23 //需重写equals()方法24 if(!al2.contains(s))25 al2.add(s);26 }27 //遍历新集合28 Iterator it2 = al2.iterator();29 while(it2.hasNext())30 {31 Student s = (Student)it2.next();32 System.out.println(s.getName()+":"+s.getAge());33 }34 }35 }
运行结果:
小明:23小红:15旺财:16小明:18小强:21
16.08 用LinkedList实现栈结构的集合代码
LinkedList list = new LinkedList();list.addFirst("hello");list.addFirst("world");list.addFirst("java");Iterator it = list.iterator();while(it.hasNext()){ System.out.println(it.next());}
16.09 用LinkedList模拟栈数据结构的集合并测试案例
自己定义一个集合类,底层可以使用LinkedList
public class MyStack { private LinkedList list; public MyStack() { list = new LinkedList(); } //添加方法 public void add(Object obj) { list.addFirst(obj); } //获取方法 public Object get() { return list.removeFirst(); } //判断是否为空方法 public boolean isEmpty() { return list.isEmpty(); }}测试类:public class Practice { public static void main(String[] args) { MyStack ms = new MyStack(); ms.add("hello"); ms.add("world"); ms.add("java"); while(!ms.isEmpty()) { System.out.println(ms.get()); } }}
16.10 泛型概述和基本使用
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayList al = new ArrayList(); 6 al.add("hello"); 7 al.add("world"); 8 al.add("java");//String 9 al.add(3);//Integer10 11 Iterator it = al.iterator();12 while(it.hasNext())13 {14 //ClassCastException15 String s = (String)it.next();16 System.out.println(s);17 }18 }19 }
上面的代码会报错,因为存储在al集合中的元素有String及Integer类型,在遍历的时候都当做String类型处理,所以报错。如果在创建对象的时候就明确元素的数据类型就不会出现问题了,在Java中这种技术成为泛型。
泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
格式:<数据类型>:此处的数据类型只能是引用类型
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayListal = new ArrayList (); 6 al.add("hello"); 7 al.add("world"); 8 al.add("java"); 9 10 Iterator it = al.iterator();11 while(it.hasNext())12 {13 String s = it.next();14 System.out.println(s);15 }16 }17 }
好处:
1:把运行时期的问题提前到了编译期间
2:避免了强制类型转换
3:优化了程序设计,解决了黄色警告线
16.11 ArrayList存储字符串并遍历泛型版
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayListal = new ArrayList (); 6 al.add("hello"); 7 al.add("world"); 8 al.add("java"); 9 10 Iterator it = al.iterator();11 while(it.hasNext())12 {13 String s = it.next();14 System.out.println(s);15 }16 System.out.println("-----");17 for (int i = 0; i < al.size(); i++) 18 {19 String s = al.get(i);20 System.out.println(s);21 }22 }23 }
16.12 ArrayList存储自定义对象并遍历泛型版
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 //泛型推断 6 // ArrayListal = new ArrayList<>(); 7 ArrayList al = new ArrayList (); 8 9 al.add(new Student("小明",23));10 al.add(new Student("小红",15));11 al.add(new Student("旺财",16));12 al.add(new Student("小强",21));13 14 Iterator it = al.iterator();15 while(it.hasNext())16 {17 Student s = it.next();18 System.out.println(s.getName()+":"+s.getAge());19 }20 }21 }
16.13 通过Object转型问题引入泛型
早期的时候,我们使用Object来代表任意的类型。
向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题。
也就是说这样的程序其实并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。
16.14 泛型类的概述及使用
泛型类:把泛型定义在类上
格式:public class 类名<泛型类型1,...>
注意:泛型类型必须是引用类型
例:
1 public class ObjectTool2 { 3 private R obj; 4 5 public R getObj() 6 { 7 return obj; 8 } 9 10 public void setObj(R obj) 11 {12 this.obj = obj;13 }14 }
测试:
ObjectToolot = new ObjectTool ();ot.setObj("hello");System.out.println(ot.getObj());
16.15 泛型方法的概述和使用
泛型方法:把泛型定义在方法上
格式:public <泛型类型> 返回类型方法名(泛型类型 ...)
例:
1 //泛型方法,参数类型与类的类型一致,类上的是什么类型,方法的参数类型就是什么类型 2 public void show(R r) 3 { 4 System.out.println(r); 5 } 6 //泛型方法,参数类型与类的类型不一致,类上的类型与方法的参数类型无关 7 //该方法可以接受任意类型 8 publicvoid method(T t) 9 {10 System.out.println(t);11 }
测试:
ObjectToolot1 = new ObjectTool ();ObjectTool ot2 = new ObjectTool ();ObjectTool ot3 = new ObjectTool ();ot1.show("hello");//类上的是什么类型,方法的参数类型就是什么类型ot2.show(25);ot3.show(true);System.out.println("----");//类上的类型与方法的参数类型无关ot1.method("hello");ot1.method(23);ot1.method(true);
16.16 泛型接口的概述和使用
泛型接口:把泛型定义在接口上
格式:public interface 接口名<泛型类型1...>
//泛型接口public interface Inter{ public abstract void show(T t);}//实现类第一种情况:已经知道是什么类型的public class InterImpl implements Inter { @Override public void show(String t) { System.out.println(t); }}//第一种情况测试:public class InterDemo { public static void main(String[] args) { Inter i = new InterImpl(); i.show("hello"); }}//实现类第二种情况:还不知道是什么类型的public class InterImpl implements Inter { @Override public void show(T t) { System.out.println(t); }}//第二种情况测试:public class InterDemo { public static void main(String[] args) { Inter i1 = new InterImpl (); Inter i2 = new InterImpl (); i1.show("hello"); i2.show(23); }}
16.17 泛型高级之通配符
泛型通配符<?>: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E: 向下限定,E及其子类
? super E: 向上限定,E及其父类
例:
public class Practice { public static void main(String[] args) { // 泛型如果明确的写的时候,前后必须一致 Collection
16.18 增强for的概述和使用
JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举
增强for概述:简化数组和Collection集合的遍历
格式:
for(元素数据类型变量 : 数组或者Collection集合)
{使用变量即可,该变量就是元素}
例:
int[] arr = {11,22,33,44,55};//增强forfor(int x : arr){ System.out.println(x);}
好处:简化遍历
注意事项:增强for的目标要判断是否为null
16.19 ArrayList存储字符串并遍历增强for版
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayListal = new ArrayList (); 6 al.add("hello"); 7 al.add("world"); 8 al.add("java"); 9 10 for(String str : al)11 {12 System.out.println(str);13 }14 }15 }
16.20 ArrayList存储自定义对象并遍历增强for版
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 ArrayListal = new ArrayList (); 6 7 al.add(new Student("小明",23)); 8 al.add(new Student("小红",15)); 9 al.add(new Student("旺财",16));10 al.add(new Student("小强",21));11 12 for(Student s : al)13 {14 System.out.println(s.getName()+":"+s.getAge());15 }16 }17 }
16.21 静态导入的概述和使用
格式:import static 包名….类名.方法名;可以直接导入到方法的级别
例:
1 import static java.lang.Math.abs; 2 import static java.lang.Math.max; 3 import static java.lang.Math.pow; 4 5 public class Practice 6 { 7 public static void main(String[] args) 8 { 9 System.out.println(abs(-10));10 System.out.println(max(20,30));11 System.out.println(pow(2,3));12 }13 }
注意事项:
1.方法必须是静态的
2.如果有多个同名的静态方法,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
16.22 可变参数的概述和使用
可变参数概述:定义方法的时候不知道该定义多少个参数
格式:修饰符返回值类型方法名(数据类型… 变量名){}
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 int result1 = sum(11,22,33); 6 int result2 = sum(11,22,33,44); 7 int result3 = sum(11,22,33,44,55); 8 System.out.println(result1); 9 System.out.println(result2);10 System.out.println(result3);11 }12 //可变参数,其实就是一个数组13 public static int sum(int... a)14 {15 int result = 0;16 for(int x : a)17 {18 result += x;19 }20 return result;21 }22 }
注意:
1.这里的变量其实是一个数组
2.如果一个方法有可变参数,并且有多个参数,那么,可变参数必须是最后一个
16.23 Arrays工具类的asList()方法的使用(数组转集合)
Arrays工具类中的一个方法:public static <T> List<T> asList(T... a)
例:
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 String[] strArray = {"hello","world","java"}; 6 Listlist = Arrays.asList(strArray); 7 for(String s : list) 8 { 9 System.out.println(s);10 }11 System.out.println("-----");12 //可变参数13 List list2 = Arrays.asList("hello","world");14 for(String s : list2)15 {16 System.out.println(s);17 }18 }19 }
运行结果:
helloworldjava-----helloWorld
注意事项:虽然可以把数组转成集合,但是集合的长度不能改变。
16.24 集合嵌套存储和遍历元素的案例代码实现
集合的嵌套遍历ArrayList嵌套ArrayList
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 创建大集合 6 ArrayList> bigArrayList = new ArrayList >(); 7 8 //创建第一个集合 9 ArrayList al1 = new ArrayList();10 al1.add(new Student("小明",23));11 al1.add(new Student("小红",12));12 al1.add(new Student("小强",26));13 al1.add(new Student("旺财",14));14 //第一个集合添加到大集合15 bigArrayList.add(al1);16 17 //创建第二个集合18 ArrayList al2 = new ArrayList();19 al1.add(new Student("唐僧",40));20 al1.add(new Student("孙悟空",28));21 al1.add(new Student("猪八戒",29));22 al1.add(new Student("沙僧",27));23 //第二个集合添加到大集合24 bigArrayList.add(al2);25 26 //创建第三个集合27 ArrayList al3 = new ArrayList();28 al1.add(new Student("宋江",40));29 al1.add(new Student("吴用",35));30 al1.add(new Student("高俅",30));31 al1.add(new Student("李师师",22));32 //第三个集合添加到大集合33 bigArrayList.add(al3);34 35 // 遍历集合36 for (ArrayList array : bigArrayList) 37 {38 for (Student s : array) 39 {40 System.out.println(s.getName() + "---" + s.getAge());41 }42 }43 }44 }
16.25 产生10个1-20之间的随机数要求随机数不能重复案例
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 创建产生随机数的对象 6 Random r = new Random(); 7 8 // 创建一个存储随机数的集合。 9 ArrayListarray = new ArrayList ();10 11 // 定义一个统计变量。从0开始。12 int count = 0;13 14 // 判断统计遍历是否小于1015 while (count < 10) 16 {17 //先产生一个随机数18 int number = r.nextInt(20) + 1;19 20 //判断该随机数在集合中是否存在。21 if(!array.contains(number))22 {23 //如果不存在:就添加,统计变量++。24 array.add(number);25 count++;26 }27 }28 29 //遍历集合30 for(Integer i : array)31 {32 System.out.println(i);33 }34 }35 }
16.26 键盘录入多个数据在控制台输出最大值案例
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 // 创建键盘录入数据对象 6 Scanner sc = new Scanner(System.in); 7 8 // 键盘录入多个数据,不知道多少个,所以用集合存储 9 ArrayListarray = new ArrayList ();10 11 // 以0结束只要键盘录入的数据是0,我就不继续录入数据了12 //定义一个记录变量13 int count = 1;14 while (true)15 {16 System.out.println("请输入第"+(count++)+"个数据");17 int number = sc.nextInt();18 if (number != 0)19 {20 array.add(number);21 } 22 else 23 break;24 }25 26 // 把集合转成数组27 // public T[] toArray(T[] a)28 Integer[] i = new Integer[array.size()];29 // Integer[] ii = array.toArray(i);30 array.toArray(i);31 System.out.println("排序前的数组是:" + arrayToString(i));32 // 对数组排序33 // public static void sort(Object[] a)34 Arrays.sort(i);35 36 // 获取该数组中的最大索引的值37 System.out.println("排序后的数组是:" + arrayToString(i) + "\r\n"38 +"最大值是:"+ i[i.length - 1]);39 }40 41 //遍历数组的方法42 public static String arrayToString(Integer[] i) 43 {44 StringBuilder sb = new StringBuilder();45 46 sb.append("[");47 for (int x = 0; x < i.length; x++) 48 {49 if (x == i.length - 1) 50 {51 sb.append(i[x]);52 } 53 else 54 {55 sb.append(i[x]).append(", ");56 }57 }58 sb.append("]");59 return sb.toString();60 }61 }
运行结果:
请输入第1个数据25请输入第2个数据15请输入第3个数据45请输入第4个数据56请输入第5个数据58请输入第6个数据48请输入第7个数据0排序前的数组是:[25, 15, 45, 56, 58, 48]排序后的数组是:[15, 25, 45, 48, 56, 58]最大值是:58