- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
集合实际上就是一个容器。可以来容纳其它类型的数据。数组其实就是一个集合。
Java 集合主要有 3 种重要的类型:
Collection是最基本的集合接口。它继承自Iterable接口,Iterable表示可迭代的,所以所有的集合元素都是可迭代可遍历的。它有两个子接口:
Collection中能存放什么元素 ?
没有使用泛型之前,Collection中可以存储Object的所有子类型。
使用了泛型之后,Collection中只能存储某个具体的类型。
返回值类型 | 方法名 | 描述 |
---|---|---|
boolean | add(Object e) | 向集合中添加元素 |
int | size() | 获取集合中元素的个数 |
void | clear() | 清空集合 |
boolean | contains(Object o) | 判断当前集合中是否包含元素o |
boolean | remove(Object o) | 删除集合中的某个元素 |
boolean | isEmpty() | 判断该集合中元素的个数是否为0 |
Object[] | toArray() | 调用这个方法可以把集合转换成数组 |
注意:集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址(或者说集合中存储的是引用)
//这里存进去的并不是int类型的1200
//这里使用了自动装箱机制 Integer x = new Integer(1200);
c.add(1200);
Iterator常用方法
返回值类型 | 方法名 | 描述 |
---|---|---|
boolean | hasNext() | 如果仍有元素可迭代就返回true |
Object | next() | 返回迭代的下一个元素 |
void | remove() | 从集合中移除next()方法返回的最后一个元素 |
注意:在迭代集合元素的过程中,不能调用集合对象的remove方法删除元素。否则会造成java.util.ConcurrentModificationException异常。正确做法是使用迭代器Iterator提供的remove方法
public static void main(String[] args) {
Collection c1 = new ArrayList(); // 创建集合对象
c1.add(1);// 添加元素
c1.add(2);// 添加元素
c1.add(3);// 添加元素
c1.add(4);// 添加元素
c1.add(1);// 添加元素
// 获取集合迭代器
Iterator it = c1.iterator();
while(it.hasNext()){
Object obj = it.next();
//c1.remove(obj);删除元素之后,集合的结构发生了变化,但是循环下一次的时候并没有重新获取迭代器
it2.remove();// 迭代器去删除时,会自动更新迭代器,并且更新集合
System.out.println(obj);
}
}
List集合中的常用方法
返回值类型 | 方法名 | 描述 |
---|---|---|
void | add(int index,Object element) | 将元素element插入到List集合的index索引处 |
Object | get(int index) | 返回列表index索引处的元素 |
Object | remove(int index) | 删除列表index索引处的元素 |
int | indexOf(Object o) | 返回对象o在List集合中出现的位置索引 |
int | LastIndexOf(Object o) | 返回对象o在List集合中最后一次出现的位置索引 |
List | subList(int fromIndex,int toIndex) | 返回从索引fromIndex(包括)到toIndex处(不包括)处的子集合 |
ArrayList集合底层是一个Object[]数组,默认初始化容量10。ArrayList集合是非线程安全的
public class ArrayListTest{
public static void main(String[] args) {
//List list = new ArrayList();默认初始化容量是10
List list = new ArrayList(4); // 指定初始化容量4
// 集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量。
System.out.println(list1.size()); // 0
list.add(1);
list.add(2);
list.add(3);
list.add(4);
// 再加一个元素
list.add(5);//数组自动扩容,增长到原容量的1.5倍
}
//第一种遍历方式:fori
for(int i = 0; i <list1.size(); i++){
Object elem = list1.get(i);
System.out.println(elem);
}
//第一种遍历方式:foreach
for (Object elem : list1) {
System.out.println(elem);
}
//第一种遍历方式:使用迭代器
Iterator iterator = list1.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
注意:并不是一创建ArrayList容器对象就初始化容量。底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10
LinkedList集合底层采用了双向链表的数据结构
LinkedList集合中常用的方法
返回值类型 | 方法名 | 描述 |
---|---|---|
void | addFirst(Object o) | 将元素o添加到集合的开头 |
void | addLast(Object o) | 将元素o添加到集合的结尾 |
Object | getFirst() | 返回集合的首元素 |
Object | getLast() | 返回集合的尾元素 |
Object | removeFirst() | 移除并返回集合的首元素 |
Object | removeLast() | 移除并返回集合的尾元素 |
public class LinkedListTest01 {
public static void main(String[] args) {
// LinkedList集合底层也是有下标的。
// LinkedList集合有初始化容量吗?没有。
List<String> list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
//第一种遍历方式:fori
for(int i = 0; i <list.size(); i++){
String str = list.get(i);
System.out.println(str);
}
//第一种遍历方式:foreach
for (String str : list) {
System.out.println(str);
}
//第一种遍历方式:使用迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String nextStr = iterator.next();
System.out.println(nextStr);
}
}
}
public class VectorTest {
public static void main(String[] args) {
// 创建一个Vector集合
List vector = new Vector();
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(5);
Iterator it = vector.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
}
如何将非线程安全的集合转换成线程安全的集合
List myList = new ArrayList(); // 非线程安全的。
// 变成线程安全的
Collections.synchronizedList(myList);
// myList集合就是线程安全的了。
myList.add("111");
myList.add("222");
myList.add("333");
Set集合存储元素的特点:无序不可重复
Set集合没有下标不能使用fori的方式遍历
HashSet集合在new的时候底层实际上new了一个HashMap集合,向HashSet集合中存放元素实际上存储到HashMap集合的key部分、HashMap集合底层是一个哈希表。
public class HashSetTest01 {
public static void main(String[] args) {
// 演示一下HashSet集合特点
Set<String> hashSet= new HashSet<>();
//String类已经重写了hashCode()方法和equals()方法
hashSet.add("hello3");// 添加元素
hashSet.add("hello4");
hashSet.add("hello1");
hashSet.add("hello2");
hashSet.add("hello3");
hashSet.add("hello3");
hashSet.add("hello3");
hashSet.add("hello3");
//第一种遍历方式:foreach
for(String s : hashSet){
System.out.println(s);
}
//第二种遍历方式:迭代器
Iterator<String> iterator = hashSet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
【运行结果】
hello1
hello4
hello2
hello3
Process finished with exit code 0
【结论】
1、存储时顺序和取出的顺序不同。
2、不可重复。
3、放到HashSet集合中的元素实际上是放到HashMap集合的key部分了。
HashSet集合是如何保证添加元素时不出现重复的 ?
保证不重复的关键在于出入对象的hashCode()方法和equals()方法。向HashSet集合中存入对象时,首先调用对象的hashCode()方法获取对象的哈希值,然后根据哈希值计算处存储位置。如果该位置上没有元素就将元素存入,如果该位置上已有元素则调用equals()方法比较两个元素是否相同,如果不相同则通过探测再散列的方法找到一个新的位置将元素存入,如果相同就不存入元素
TreeSet集合在new的时候底层实际上new了一个TreeMap集合,向TreeSet集合中存放元素实际上存储到TreeMap集合的key部分。TreeMap集合底层是一个二叉树。
TreeSet集合存储元素特点:
1、无序不可重复的,但是存储的元素可以自动按照大小顺序排序!
2、无序:这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
TreeSet中定义的方法
返回类型 | 方法名 | 描述 |
---|---|---|
Object | first() | 返回集合中的最低元素 |
Object | last() | 返回集合中的最高元素 |
Comparator<? super E> | comparator() | 返回对此集合中元素进行排序的比较器 |
public class TreeSetTest01 {
public static void main(String[] args) {
// 创建集合对象
Set<String> strs = new TreeSet<>();
// 添加元素
strs.add("A");
strs.add("B");
strs.add("Z");
strs.add("Y");
strs.add("Z");
strs.add("K");
for(String s : strs){
System.out.print(s+" ");//从小到大自动排序
}
}
}
【输出结果】
A B K M Y Z
Process finished with exit code 0
TreeSet集合中自定义类型元素可排序的二种方式
//1、实现Comparable接口并且重写compareTo方法
public class Customer implements Comparable<Customer>{
int age;
public Customer(int age){
this.age = age;
}
public int compareTo(Customer c) {
return c.age - this.age;
}
}
//2、使用比较器
public class TreeSetTest {
public static void main(String[] args) {
// 给构造方法传递一个比较器。(匿名内部类)也可以单独编写一个比较器
TreeSet<Customer> customerList = new TreeSet<>(new Comparator<WuGui>() {
@Override
public int compare(Customer c1, Customer c2) {
return c1.age - c2.age;
}
});
customerList.add(new Customer(20));
customerList.add(new Customer(30));
customerList.add(new Customer(18));
for(Customer customer: customerList){
System.out.println(customer);
}
}
}
Comparable和Comparator怎么选择呢 ?
返回值类型 | 方法名 | 描述 |
---|---|---|
void | put(K key, V value) | 向Map集合中添加键值对 |
Object | get(Object key) | 通过key获取value |
void | clear() | 清空Map集合 |
boolean | containsKey(Object key) | 判断Map中是否包含某个key |
boolean | containsValue(Object value) | 判断Map中是否包含某个value |
boolean | isEmpty() | 判断Map集合中元素个数是否为0 |
V | remove(Object key) | 通过key删除键值对 |
int | size() | 获取Map集合中键值对的个数。 |
Collection<V> | values() | 获取Map集合中所有的value,返回一个Collection |
Set<K> | keySet() | 获取Map集合所有的key(所有的键是一个set集合) |
Set<Map.Entry<K,V>> | entrySet() | 将Map集合转换成Set集合 |
public class MapTest {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "zhangsan");
map.put(2, "lisi");
map.put(3, "wangwu");
map.put(4, "zhaoliu");
// 第一种方式:获取所有的key,通过遍历key,来遍历value
Set<Integer> keys = map.keySet();
for(Integer key : keys){// foreach遍历,当然也可以使用迭代器遍历
System.out.println(key + "=" + map.get(key));
}
// 第二种方式:Set<Map.Entry<K,V>> entrySet()
// 这个方法是把Map集合直接全部转换成Set集合。
// Set集合中元素的类型是:Map.Entry
Set<Map.Entry<Integer,String>> set = map.entrySet();
for(Map.Entry<Integer,String> node : set){// foreach遍历,当然也可以使用迭代器遍历
System.out.println(node.getKey() + "--->" + node.getValue());
}
}
}
public class HashMapTest {
public static void main(String[] args) {
// Integer是key,它的hashCode和equals都重写了。
Map<Integer,String> map = new HashMap<>();
map.put(1, "zhangsan");
map.put(6, "lisi");
map.put(7, "wangwu");
map.put(2, "zhaoliu");
map.put(2, "king"); //key重复的时候value会自动覆盖。
System.out.println(map.size()); // 4
// 遍历Map集合
Set<Map.Entry<Integer,String>> set = map.entrySet();
for(Map.Entry<Integer,String> entry : set){
// 验证结果:HashMap集合key部分元素:无序不可重复。
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
}
Map map = new Hashtable();
map.put(null, "123");//NullPointerException
map.put(100, null);//NullPointerException
public class PropertiesTest {
public static void main(String[] args) {
// 创建一个Properties对象
Properties pro = new Properties();
// 需要掌握Properties的两个方法,一个存,一个取。
pro.setProperty("url", "jdbc:mysql://localhost:3306/whydb");
pro.setProperty("driver","com.mysql.jdbc.Driver");
pro.setProperty("username", "root");
pro.setProperty("password", "123");
// 通过key获取value
String url = pro.getProperty("url");
String driver = pro.getProperty("driver");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(url);
System.out.println(driver);
System.out.println(username);
System.out.println(password);
}
}
TreeMap集合也是用来存储键值映射关系的,TreeMap不允许出现重复的键,该映射关系根据其键的自然顺序进行排序,或者根据创建映射时提供的Comparator进行排序。TreeMap的底层采用了二叉树这种数据结构
public class HashtableTest01 {
public static void main(String[] args) {
Map<Integer,String > treeMap = new TreeMap<>();
treeMap.put(1,"张三");
treeMap.put(9,"李四");
treeMap.put(8,"王五");
treeMap.put(2,"赵六");
Set<Map.Entry<Integer, String>> entries = treeMap.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey()+"=="+entry.getValue());
}
}
}
【运行结果】
1==张三
2==赵六
8==王五
9==李四
Process finished with exit code 0
Collections常用方法
返回类型 | 方法名 | 描述 |
---|---|---|
static boolean | addAll(Collection<? super T>,T…elements) | 将所有指定元素添加到Collection中 |
static void | reserve(List<?> list) | 反转指定列表中的元素 |
static void | shuffle(List<?> list) | 使用默认随机源对指定列表进行置换 |
static void | sort(List<?> list) | 根据元素的自然顺序进行升序排序 |
static void | swap(List<?> list,int i,int j) | 将指定列表中i处元素和j处元素进行交换 |
static int | binarySearch(List<?> list,Object key) | 使用二分查找搜索指定列表 |
static Object | max(Collection col) | 根据元素的自然顺序返回给定集合中的最大元素 |
static Object | min(Collection col) | 根据元素的自然顺序返回给定集合中的最小元素 |
static boolean | replaceAll(List list,Object oldVal,Object newVal) | 使用newVal替换列表中所有的oldVal |
static List<T> | synchronizedList(List<T> list) | 将指定集合转换成线程安全 |
1、定义 设 \(u\) 和 \(v\) 为一张图上的任意两个节点。令 \(c(u, v)\) 为它们之间的边的容量, \(f(u, v)\) 为它们之间的流量,则需要满足以
1、前言 工作中涉及到文件系统,有时候需要判断文件和目录是否存在。我结合apue第四章文件和目录,总结一下如何正确判断文件和目录是否存在,方便以后查询。 2、stat系列函数 stat函数用来
并查集(Union-Find Set): 一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组 (2) 将元素a和b合并为同一组。 注意:并查集不能将在同一组的元素拆
当下,注解非常流行,以前很长篇的代码,现在基本上一个注解就能搞定。 那,在Mybatis中又有哪些注解呢? Mybatis中的注解基本上都在org.apache.ibatis.annotat
指针操作数组,方法一是p+index,方法二是p[index],第二种方法跟数组访问方法是一样的。 数组引用返回的是数组的第一个元素的指针地址。 可以将指针指向数组的任意元素,然后从那里开始访问
通常部署完php环境后会进行一些安全设置,除了熟悉各种php漏洞外,还可以通过配置php.ini来加固PHP的运行环境,PHP官方也曾经多次修改php.ini的默认设置。 下面对php.ini中一
在JavaScript中,使用typeof可以检测基本数据类型,使用instanceof可以检测引用数据类型。在PHP中,也有检测数据类型的方法,具体如下: 1、输出变量的数据类型(gettype
把图片缓存到本地,在很多场景都会用到,如果只是存储文件信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存储图片到沙盒就没那么方便了。这里简单介绍两种保存图片到沙盒的方法。
(1)需要安装docker容器,在docker容器内安装jenkins,gogs,tomcat。 新建maven项目,添加findbugs plugin。 使用docker
今天主题是实现并发服务器,实现方法有多种版本,先从简单的单进程代码实现到多进程,多线程的实现,最终引入一些高级模块来实现并发TCP服务器。 说到TCP,想起吐槽大会有个段子提到三次握手,也只有程序
如下所示: Ctrl+1或F2快速修复 Ctrl+D快捷删除行 Shift+Enter 快速切换到下一行,在本行的任何位置都可 Ctrl+F11快速运行代码 Alt+上下键 快速移动行(可
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。 JSP编译后是”类servlet”。 Servlet和JSP最主要的不同点在于,Servlet的应用逻辑
Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键
读取Java文件到byte数组的三种方法(总结) ? 1
用java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:
1、简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2…,sn)
java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx、Apache等通用web服务器软件。 一、Tomcat Tomcat是Apache 软件基
事务作为抽象层,允许应用忽略DB 内部一些复杂并发问题和某些硬件、软件故障,简化应用层的处理逻辑:事务中止(transaction abort),而应用仅需重试。对复杂访问模式,事务可大大减少需要考虑
我们在本教程学习了如何描述 XML 文档的结构 我们学习到了如何使用 DTD 来定义一个 XML 文档的合法元素,以及如何在我们的 XML 内部或者作为一个外部引用来声明 DTD 我们学习了如何为
在这个XPath 基础教程中我们讲解了如何在 XML 文档中查找信息 我们可以使用 XPath 的元素和属性在 XML 文档中进行导航 我们也学习了如何使用 XPath 中内建的某些标准函数 如
我是一名优秀的程序员,十分优秀!