gather
gather
1.基础关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-004gQefb-1681218871575)(C:\\Users\\清劭\\AppData\\Roaming\\Typora\\typora-user-images\\image-20221122175903544.png)]
2.Collection
- Collection接口实现类的特点:
- 可以存放多个元素,每个元素可以是Object。
- 有些类可以存放重复的元素,有些不能存放重复的元素。
- 有些类是有序的(List),有些类是无序的(Set)
- Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的
- Collection方法
package com.gather.z_new;import java.util.ArrayList;
import java.util.List;public class CollectionMethod {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();// add:添加单个元素list.add("jack");//放基本类型有一个自动装箱的过程;int类型转化为Interger类型list.add(10);list.add(true);System.out.println("list=" + list);//remove:删除元素//list.remove(0);//根据索引删除,删除第一个元素,返回一个被删除Object类型的对象list.remove(true);//指定删除对象,删除true,返回一个Boolean类型System.out.println("list=" + list);//contains:查找元素是否存在,返回一个Boolean类型System.out.println(list.contains("jack"));//size:获取元素个数,返回一个int类型System.out.println(list.size());//isEmpty:判断是否为空,返回一个boolean类型System.out.println(list.isEmpty());//clear:清空,返回voidlist.clear();System.out.println("list="+list);//addAll:添加多个元素,返回boolean类型,参数是集合ArrayList list2 = new ArrayList();list2.add("红楼梦");list2.add("三国演义");list.addAll(list2);System.out.println("list="+list);//containsAll;查找多个元素是否存在,参数是集合,回boolean类型System.out.println(list.containsAll(list2));//removeAll:删除多个元素,参数是集合,回boolean类型list.add("聊斋");list.removeAll(list2);System.out.println("list="+list);}
}
-
Collection接口的遍历
- Iterator对象遍历
每个实现了Collection接口的子接口或者类都有一个iterator()方法,其用于遍历集合,不能遍历数组
package com.gather.z_new;import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;public class CollectionIterator {@SuppressWarnings({"all"})public static void main(String[] args) {Collection collection = new ArrayList();collection.add(new Book("三国演义", "罗贯中", 10.1));collection.add(new Book("小李飞刀", "古龙", 5.1));collection.add(new Book("红楼梦", "曹雪芹", 36.6));System.out.println(collection);//遍历集合()//先得到collection的迭代器Iterator iterator = collection.iterator();//用while循环(快捷键itit)while (iterator.hasNext()){//hasNext()判断是否还有数据,返回Boolean//next()返回下一个元素,返回类型ObjectObject obj = iterator.next();System.out.println(obj);}//当退出while循环后,iterator迭代器,指向最后的元素//如果希望再次遍历需要重置迭代器iterator=collection.iterator();} }class Book {private String name;private String author;private double price;public Book() {}public Book(String name, String author, double price) {this.name = name;this.author = author;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\\'' +", author='" + author + '\\'' +", price=" + price +'}';} }
- 增强for循环
底层逻辑还是调用了iterator()迭代器,且调用完还进行了重置,其可以用于数组
package com.gather.z_new;import java.util.ArrayList; import java.util.Collection;public class CollectionFor {@SuppressWarnings({"all"})public static void main(String[] args) {Collection collection = new ArrayList();collection.add(new Book("三国演义", "罗贯中", 10.1));collection.add(new Book("小李飞刀", "古龙", 5.1));collection.add(new Book("红楼梦", "曹雪芹", 36.6));//使用增强for循环//1.不光可以用在集合,还可以在数组上使用//2.底层逻辑还是iterator迭代器,且迭代器重置了for (Object o :collection) {System.out.println(o);}} }
注意:其实也可以使用普通的循环语句,实现了其接口的都可以通过该方法来遍历
3.List
-
List接口实现类特点:
- 元素有序,可以重复
- 没有元素存在索引,且索引从0开始
- 其实现类有很多,最常见的有:ArrayList,LinkedList,Vector
-
List方法
package com.gather.z_new;import java.util.ArrayList; import java.util.List;public class ListMethod {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add("张三丰");list.add("贾宝玉");//add(int index),在index的位置插入一个对象,返回类型voidlist.add(1, "周万里");System.out.println(list);//addAll(int index ,Collection col),从index位置开始将col中的所有元素添加进来,返回一个boolean类型List list2 = new ArrayList();list2.add("jack");list2.add("tom");list.addAll(1, list2);System.out.println(list);//get(),获取指定位置的元素,返回一个Object类型System.out.println(list.get(1));//indexOf(Object obj),返回obj在集合中首次出现的位置,返回一个int类型System.out.println(list.indexOf("tom"));//2//lastIndexOf(Object obj),返回obj在集合中末次出现的位置,返回一个int类型list.add("周万里");System.out.println(list.lastIndexOf("周万里"));//remove(int index);移除index位置的元素,并返回此元素,返回类型为Objectlist.remove(0);System.out.println(list);//set(int index,Object obj),设置指定index位置的元素为obj,相当于替换,索引必须存在,在最后也不行,并且返回被替换的元素,且为Object类型list.set(1, "玛丽");System.out.println(list);//subList(int fromIndex,int toIndex)返回fromIndex到toIndex位置的子集合,返回类型为集合//返回的子集合是前开后闭的List returnList = list.subList(0, 2);System.out.println(returnList);}}
-
List的遍历案例
使用List的是西安类添加三本书,并遍历,打印效果
名称:XXX 价格:XX 作者:XX
名称:XXX 价格:XX 作者:XX
名称:XXX 价格:XX 作者:XX
要求:按价格排序,从低到高
package com.gather.z_new.exercise;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;@SuppressWarnings({"all"})
public class ListExercise {public static void sort(List list) {for (int i = 0; i < list.size() - 1; i++) {for (int j = list.size() - 1; j > i; j--) {if (((Book) list.get(j)).getPrice() < ((Book) list.get(j - 1)).getPrice()) {Book temp;temp = (Book) list.get(j);list.set(j, list.get(j - 1));list.set(j - 1, temp);}}}}public static void main(String[] args) {List list = new ArrayList();list.add(new Book("水浒传", 15.10, "施耐庵"));list.add(new Book("西游记", 10.10, "吴承恩"));list.add(new Book("红楼梦", 36.60, "曹雪芹"));sort(list);Iterator iterator = list.iterator();while (iterator.hasNext()) {Book book = (Book) iterator.next();System.out.println(book);}}
}class Book {private String name;private double price;private String author;public Book() {}public Book(String name, double price, String author) {this.name = name;this.price = price;this.author = author;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}@Overridepublic String toString() {return "名称: " + name + "\\t\\t价格:" + price + "\\t\\t作者:" + author;}
}
4.ArrayList
- ArrayList注意事项
- 可以加入null,且可以加入多个
- ArrayList是由数组来实现数据储存的(看源码)
- ArrayList基本等同于Vector,除了ArrayList是线程不安全的(执行效率高)(看源码) ,在多线程情况下,不建议使用ArrayList
- ArrayList底层结构和源码分析
- ArrayList中维护了一个Object类型的数组elementData
- 当创建ArrayList对象时,如果使用无参构造器,则初始elementData容量为0,第一次添加,则扩容为10,如需再次扩容,则扩容elementData为1.5倍
- 如果是使用的是指定大小的构造器,则初始elementData容量为指定大小,如需再次扩容,则直接扩容elementData为1.5倍
5.Vector
- 底层是一个对象数组,protected Object elementData;
- Vector是线程同步的,即是线程安全的,Vector类的操作方法带有synchronized
- 在开发中,需要线程同步安全时,考虑使用Vector
- 扩容机制:
- 如果是无参,默认10,满后按照两倍扩容
- 如果指定大小,则每次直接按照两倍扩容
6.LinkedList
-
LinkedList底层实现了双向链表和双端队列特点
-
可以添加任意元素(元素可以重复),包括null
-
线程不安全,没有实现同步
-
底层的原理:
- 底层是一个和双向链表
- 维护了两个属性first,list分别指向首字节点和尾字节点
- 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表
- 所以LinkedList的元素的添加和删除,不是通过数组来完成的,相对来说效率较高
- 双向链表的基础逻辑
public class LinkedListTest {public static void main(String[] args) {//模拟一个双向列表Node jack = new Node("jack");Node tom = new Node("tom");Node zwl = new Node("zwl");//连接三个结点,形成双向列表jack.next = tom;tom.next = zwl;zwl.pre = tom;tom.pre = jack;Node first = jack;//头结点Node last = zwl;//尾结点//重头到尾进行遍历while (true) {if (first == null) {break;}System.out.println(first);first = first.next;}//重置firstfirst = jack;//从尾到头遍历while (true) {if (last == null) {break;}System.out.println(last);last = last.pre;}//重置lastlast = zwl;//添加一个对象//在tom和zwl之间插入一个smithNode smith = new Node("smith");tom.next = smith;smith.next = zwl;zwl.pre = smith;smith.pre = tom;while (true) {if (first == null) {break;}System.out.println(first);first = first.next;}//重置firstfirst = jack;while (true) {if (last == null) {break;}System.out.println(last);last = last.pre;}//重置lastlast = zwl;}
}//定义一个Node类,Node对象表示双向链表的一个结点
class Node {public Object item;//存放真正的public Node next;//指向下一个结点public Node pre;//指向上一个结点public Node(Object name) {this.item = name;}@Overridepublic String toString() {return "Node name=" + item;}
}
- LinkedList增删改查(CRUD)
-
List集合选择
底层结构 增删效率 改查的效率 ArrayList 可变数组 较低,数组扩容 较高 LinkedList 双向链表 较高,链表追加 较低 如何选择ArrayList和LinkedList
- 查改操作多,选择ArrayList
- 增删操作多,选择LinkedList
- 在一般来说,实际开发,百分之八十到九十都是查询,所以大部分情况下都会选择ArrayList
- 在项目中分模块,也可能某些模块使用LinkedList,有些模块使用ArrayList
注意:
- Vector是线程安全的(慢),ArrayList是线程不安全的(快),其余并没有什么不同.
- LinkedList也是线程不安全的.
7.Set
- 添加和取出的顺序不一样,取出的顺序是固定的(根据哈希值)
- 不允许重复元素,所以最多包含一个null
- 其有很多其他的实现类,最常见的是HashSet和TreeSet
常用方法:和List接口一样,是Collection接口的子接口,常用方法和Collection接口一样.
SET接口的遍历:
- 迭代器
- 增强for循环
- 不能使用索引的方法遍历.
package com.gather.z_new;import java.util.HashSet;
import java.util.Set;@SuppressWarnings({"all"})
public class SetMethod {public static void main(String[] args) {Set set = new HashSet();set.add("john");set.add("lucy");set.add("john");set.add("jack");set.add(null);set.add(null);System.out.println(set);}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kj2xn3dV-1681218871577)(C:\\Users\\清劭\\AppData\\Roaming\\Typora\\typora-user-images\\image-20221123235730199.png)]
泛型
-
Java泛型是JDK1.5引入的新特性,其本质是参数化类型,把类型作为参数传递。
-
参见形式泛型类、泛型接口、泛型方法。
-
语法:
<T…> T称为占位符,表示引用类型
-
好处:
- 提高代码的重用性
- 防止类型转换异常,提高代码安全性
泛型类
package com.gather.z_new.generic;/ 泛型类* 语法,类名<T>* T是类型占位符表示一种应用类型,如果编写多个使用逗号隔开* */
public class MyGeneric<T> {//创建变量T t;//作为方法的参数public void show(T t) {//不能实例化System.out.println(t);}//作为方法的返回值public T getT() {return t;}}
package com.gather.z_new.generic;public class TestGeneric {public static void main(String[] args) {//使用泛型类对象MyGeneric<String> myGeneric = new MyGeneric<String>();myGeneric.t = "hello";myGeneric.show("大家好,加油");String string = myGeneric.getT();MyGeneric<Integer> myGeneric1 = new MyGeneric<>();myGeneric1.t = 100;myGeneric1.show(200);Integer integer = myGeneric1.getT();}
}
泛型接口
的返回值
public T getT() {
return t;
}
}
```java
package com.gather.z_new.generic;public class TestGeneric {public static void main(String[] args) {//使用泛型类对象MyGeneric<String> myGeneric = new MyGeneric<String>();myGeneric.t = "hello";myGeneric.show("大家好,加油");String string = myGeneric.getT();MyGeneric<Integer> myGeneric1 = new MyGeneric<>();myGeneric1.t = 100;myGeneric1.show(200);Integer integer = myGeneric1.getT();}
}