List系列集合:
1.集合是支持泛型的,可以在编译阶段约束集合只能操作某种数据类型
2.集合只支持引用数据类型,在集合中存储的元素都认为是对象
Collection常用API:
package wryyyyy;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo
{
public static void main(String[] args)
{
//1.在添加元素这里,有的集合不允许重复
Collection<String> list = new ArrayList<>();
list.add("我要吃鱼");
list.add("wwwww");
list.add("Java");
System.out.println(list);
//2.清空
//list.clear();
System.out.println(list);
//3.判断集合是否为空,空则返回true
System.out.println(list.isEmpty());
//4.获取集合大小
System.out.println(list.size());
//5.判断集合有没有包含某个元素
System.out.println(list.contains("wwwww"));
//6.删除某个元素,如果有两个相同元素默认删前面的
//如果要删除所有的相同元素应遍历
//Collection不支持索引,只能通过元素值来删
list.remove("wwwww");
System.out.println(list);
//7.把集合转换成数组
Object[] arrs = list.toArray(new String[0]);//注意转成Object
//8.合并两个集合的元素
Collection<String> list1 = new ArrayList();
list1.add("123");
list1.add("abc");
list.addAll(list1);//把list1中元素全部拷贝到list
System.out.println(list);
}
}
Collection集合的遍历:
1.迭代器(集合的专用遍历方式)
//得到当前集合的迭代器对象
Iterator<String> it = list.iterator();
//String ele = it.next();//取一个元素
//System.out.println(ele);//注意不要越界
while (it.hasNext())
{
String ele = it.next();
System.out.println(ele);
}
2.foreach遍历/增强for循环(集合数组都可以遍历)
for (String ele:list)//快捷方式:list. for
{
System.out.println(ele);//这里ele当做形参,修改无意义
}
Lambda表达式:
list.forEach(new Consumer<String>()//Consumer是一个接口,不能有对象,只能new一个匿名形式
{
@Override
public void accept(String s)
{
System.out.println(s);
}
});
//简化
list.forEach(s->{
System.out.println(s);
});
list.forEach(s->System.out.println(s));
list.forEach(System.out::println);
数据结构:
栈:先进后出,后进先出
堆:先进先出 ,后进后出
数组:根据索引的查询速度快(元素在内存中是连续存储的)
链表:元素在内存中不连续存储,每个元素结点包含数据和下一个结点的地址;
查询慢,无论查询那个数据都要从头开始找;增删块(但找到这个元素慢)。
二叉树:
检索数据快。(以后会具体学习)
List系列集合:
List集合独有方法:
package wryyyyy;
import java.util.ArrayList;
import java.util.List;
public class CollectionDemo1
{
public static void main(String[] args)
{
List<String> list = new ArrayList<>();
list.add("Java1");
list.add("Java2");
list.add("Java3");
list.add("Java4");
list.add(2,"Java2.5");
System.out.println(list);
list.remove("Java2.5");//有返回值,返回被删除元素
System.out.println(list.get(2));
list.set(2,"modify");//有返回值,返回修改前的数据
}
}
ArrayList集合底层原理:
当插入元素超过10时要进行扩容
LinkedList集合:
底层数据结构是双链表,查询慢,首尾操作速度快。
LinkedList可以完成队列结构和栈结构。
package wryyyyy;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class CollectionDemo1
{
public static void main(String[] args)
{
LinkedList <String> stack = new LinkedList<>();//要用独有功能,所以不用多态写
//压栈,入栈
stack.addFirst("111");//专业的应写为push
stack.addFirst("222");
stack.addFirst("333");
stack.addFirst("444");//每次加第一个位置把上一个压下去
//出栈,弹栈
System.out.println(stack.removeFirst());//取出并删除//专业的应写为pop
System.out.println(stack);
LinkedList<String> queue = new LinkedList<>();
//入队
queue.addLast("111");//专业的应写为offerLast
queue.addLast("222");
queue.addLast("333");
queue.addLast("444");
//出队
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue);
}
}
并发修改异常问题:
迭代器:
Iterator<String> it = list.iterator();
while (it.hasNext())
{
String ele = it.next();
if ("Java2".equals(ele));
{
// list.remove("Java2");//错误的,删掉之后后面的元素会往前走
it.remove();//用迭代器删除当前所在元素时,不会后移
}
}
System.out.println(list);
foreach,Lambda表达式:不能用于遍历删除。
解决删除某个元素之后后面元素前移导致跳位(fori):
方法1:remove时i--(删除成功后退一步)
方法2:倒序循环
泛型:
泛型可以在很多地方进行定义:
类后面 -> 泛型类
方法声明上 -> 泛型方法
接口后面 -> 泛型接口
自定义泛型类:
package wryyyyy;
public class CollectionDemo1
{
public static void main(String[] args)
{
//模拟ArrayList定义一个MyArrayList
MyArrayList<String> list = new MyArrayList<>();
list.add("Java1");
list.add("Java2");
list.add("Java3");
list.remove("Java1");
System.out.println(list);
}
}
自定义泛型方法:
方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性
泛型方法的原理:把出现泛型变量的地方全部替换成真实数据类型
package wryyyyy;
import java.io.InputStream;
public class CollectionDemo1
{
public static void main(String[] args)
{
//需求:给一个任意类型的数组,都能返回它的内容
String[] names = {"鱼","虾","蟹"};
printArray(names);
Integer[] ages = {10,20,30};
printArray(ages);
}
public static <T> void printArray(T[] arr)//所有类型都可以接收
{
if (arr!=null)
{
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++)
{
sb.append(arr[i]).append(i== arr.length-1?"":",");
}
sb.append("]");
System.out.println(sb);
}
else
{
System.out.println(arr);
}
}
}
自定义泛型接口:
package wryyyyy;
public interface Data<E>
{
void add(E e);
void delete(int id);
void update(E e);
void queryById(int id);
}
public class TeacherData implements Data<Teacher>
泛型语法知识(泛型通配符,上下限):
通配符:?,可以在使用泛型的时候代表一切类型
E D K V:在定义泛型时使用
package wryyyyy;
import java.awt.*;
import java.io.InputStream;
import java.util.ArrayList;
public class CollectionDemo1
{
public static void main(String[] args) {
//开发一个飞车游戏,让所有汽车都能参加比赛
}
public static void go(ArrayList<? extends Car> cars) {
}
}
class BENZ extends Car {
}
class BMW extends Car {
}
class Car {
}
Set系列集合:
(Set集合在功能上与Collection集合基本一致)
(无序不是指每次启动都无序)
package wryyyyy;
import java.util.*;
import java.util.function.Consumer;
public class CollectionDemo
{
public static void main(String[] args)
{
Set<String> sets = new LinkedHashSet<>();
sets.add("Java");
sets.add("Java");
sets.add("Mysql");
sets.add("HTML");
sets.add("HTML");
sets.add("Java");
sets.add("Java");
System.out.println(sets);//[Java, Mysql, HTML]
}
}
HashSet集合:
如果希望Set集合认为两个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法
package wryyyyy;
import java.util.*;
import java.util.function.Consumer;
public class CollectionDemo
{
public static void main(String[] args)
{
Set<Student> sets = new HashSet<>();
Student s1 = new Student("小王",20,'男');
Student s2 = new Student("小王",20,'男');
Student s3 = new Student("小于",21,'男');
sets.add(s1);
sets.add(s2);
sets.add(s3);
System.out.println(sets);
//Set集合重复的原因:先判断哈希值,再判断equals
//使用equals and hashCode重写之后两个对象哈希值一样
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
}
LinkedHashSet集合:
TreeSet集合:
Set<Integer> sets = new TreeSet<>();
sets.add(23);
sets.add(46);
sets.add(12);
sets.add(23);
System.out.println(sets);//[12, 23, 46]
//自定义排序规则 //方法1:让自定义的类实现comparable接口重写里面的compareTo方法来定制比较规则
package wryyyyy;
public class Apple implements Comparable<Apple>
{
private String name;
private String color;
private double price;
private int weight;
//省略
@Override
public int compareTo(Apple o) {
//按照重量进行比较
return this.weight-o.weight >= 0 ? 1: -1;
}
}
//方法2:TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则
//就近原则,优先用集合自带比较规则
{
Set<Apple> apples = new TreeSet<>(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight()- o2.getWeight();//升序
}
});
//就近原则,优先用集合自带比较规则
{
Set<Apple> apples = new TreeSet<>(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return Double.compare(o2.getPrice(),o1.getPrice());//升序
}
});
简化:
Set<Apple> apples = new TreeSet<>((o1,o2)->Double.compare(o2.getPrice(), o1.getPrice()));
可变参数:
package wryyyyy;
import java.util.Arrays;
public class MethodDemo
{
public static void main(String[] args)
{
sum();
sum(10);
sum(10,20,30);
sum(new int[]{10,20,30,40,50});
}
public static void sum(int ... nums)
{
//可变参数在方法内部其实就是一个数组
System.out.println("元素个数:"+nums.length);
System.out.println("元素内容:"+Arrays.toString(nums));
}
}
Collections集合工具类:
Collections排序相关API(只能对于List集合排序):
package wryyyyy;
import java.util.*;
import java.util.function.Consumer;
public class CollectionDemo
{
public static void main(String[] args)
{
//List names = new ArrayList<>();
//Collections.addAll(names,"Java","Html","C",new int[]{1,2,3});
List<String> names = new ArrayList<>();
//批量添加
Collections.addAll(names,"Java","Html","C","Python");
System.out.println(names);
//打乱list集合顺序
Collections.shuffle(names);
System.out.println(names);
//排序
List<Integer> list = new ArrayList<>();
Collections.addAll(list,12,26,74,90,3);
Collections.sort(list);
System.out.println(list);
//自定义排序方法2:
List<Apple> apples = new ArrayList<>();
Collections.sort(apples, new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return Double.compare(o1.getPrice(), o2.getPrice());//自定义比较器优先于自带比较规则
}
});
//简化
Collections.sort(apples,((o1, o2) -> Double.compare(o1.getPrice(),o2.getPrice())));
System.out.println(list);
}
}