集合在数组的基础上,可变长度,存储类容可以不同类型(一般只用一种),但只能是引用类型。
有序的可以存放相同类型的的糖果盒

List list = new ArrayList();
// 向列表的尾部追加指定的元素
list.add("lwc");
// 在列表的指定位置插入指定元素
list.add(1, "nxj");
// 追加指定 collection 中的所有元素到此列表的结尾
list.addAll(new ArrayList());
// 从列表中移除所有元素
list.clear();
// 如果列表包含指定的元素,则返回true
list.contains("nxj");
// 如果列表包含指定 collection 的所有元素,则返回 true
list.containsAll(new ArrayList());
// 比较指定的对象与列表是否相等
list.equals(new ArrayList());
// 返回列表中指定位置的元素
list.get(0);
// 返回列表的哈希码值
list.hashCode();
// 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
list.indexOf("lwc");
// 返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1
list.lastIndexOf("lwc");
// 如果列表不包含元素,则返回 true
list.isEmpty();
// 移除列表中指定位置的元素
list.remove(0);
// 移除列表中出现的首个指定元素
list.remove("lwc");
// 从列表中移除指定 collection 中包含的所有元素
list.removeAll(new ArrayList());
// 用指定元素替换列表中指定位置的元素
list.set(0, "lp");
// 返回列表中的元素数
list.size();
// 返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分视图
list.subList(1, 2);
// 返回以正确顺序包含列表中的所有元素的数组
list.toArray();
// 返回以正确顺序包含列表中所有元素的数组
list.toArray(new String[] { "a", "b" });
public interface List<E> extends Collection<E>
底层的数据结构使用的是数组结构(数组长度是可变的百分之五十延长)(特点是查询很快,但增删较慢)线程不同步。
public class LIST {
public static void main(String[] args) {
//创建List类型集合
List myList = new ArrayList();
//添加元素
myList.add("A"); //默认都是向集合末尾添加元素
myList.add("B");
myList.add("C");
myList.add("D");
//1. 在列表的指定位置插入元素(第一个参数是下标)
//这个方法使用不多,因为对于ArrayList集合来说效率比较低
myList.add(1, "king");
//迭代
Iterator it = myList.iterator();
while (it.hasNext()){
Object elt = it.next();
System.out.println(elt); //A B C D
}
//2. 根据下标获取元素
Object firstObj = myList.get(0);
System.out.println(firstObj);
//因为有下标,所以List集合有自己比较特殊的遍历方式
//通过下标遍历,(List集合特有的方法)
for (int i = 0; i < myList.size(); i++) {
Object obj = myList.get(i);
System.out.println(obj);
}
//3. 获取指定对象第一次出现处的索引
System.out.println(myList.indexOf("king")); // 1
//4. 获取指定对象最后一次出现处的索引
System.out.println(myList.lastIndexOf("C")); //3
//5. 删除指定下标位置的元素
myList.remove(0);
System.out.println(myList.size());
System.out.println("=====================");
//6. 修改指定位置的元素
myList.set(2,"Soft");
//遍历集合
for (int i = 0; i < myList.size(); i++) {
Object obj = myList.get(i);
System.out.println(obj); //king B Soft D
}
}
}
底层的数据结构是链表结构(特点是查询较慢,增删较快)
1,由于链表上的元素空间存储内存地址不连续所以随机增删元素的时候不会有大量元素位移,因此随机增删效率较高
2.在以后的开发中,如果遇到随机增删集合中元素的业务比较多,建议使用LinkedList
3.缺点:不能通过数学表达式计算被查找元素的内存地址,每一次查找都是从头结点开始遍历,直到找到为止,所以LinkedList集合检索/查找效率较低
package com.collection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class LinkedListTest01 {
public static void main(String[] args) {
//LinkedList集合底层也是有下标的
//注意:ArrayList之所以检索效率比较高,不是单纯因为下标的原因,是因为底层数组发挥的作用
//LinkedList集合照样有下标,但是检索/查找某个元素的时候效率比较低,因为只能从节点开始一个一个遍历
List list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
System.out.println(obj);
}
//LinkList集合有初始化容量吗?
//最初这个链表中没有任何元素,first和last引用都是null
//不管是LinkedList还是ArrayList,以后写代码时不需要关心具体是哪个集合
//因为我们要面向接口编程,调用的方法都是接口中的方法
//List list2 = new ArrayList(); 这样写底层用了数组
List list2 = new LinkedList(); //这样写底层用来双向链表
list2.add("123");
list2.add("456");
list2.add("789");
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
}
}
底层是数组数据结构 线程同步(数组长度是可变的百分之百延长)(无论查询还是增删都很慢,被ArrayList替代了)
Vector在所有的方法都是线程同步的,都带有synchronized关键字,是线程安全的,效率较低,使用较少
package com.collection;
import java.util.*;
public class VectorTest {
public static void main(String[] args) {
//创建一个Vector集合
//Vector vector = new Vector();
List vector = new Vector();
//添加元素
//默认容量10个
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(5);
vector.add(5);
vector.add(6);
vector.add(7);
vector.add(8);
vector.add(9);
vector.add(10);
//满了之后扩容(扩容是)
vector.add(11);
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");
}
}
一个只能存放不同糖果而且无序的糖果罐
特点:快,无序。
实际生成了哈希表,方便快熟查找。
从而可以自由增加HashCode的长度。
存储时顺序和取出的顺序不同,不可重复放到HashSet集合中的元素实际上是放到HashMap集合的key部分了
public static void main(String[] args) {
// 创建存储字符串的HashSet集合
Set<String> objects = new HashSet<>();
}
| 方法名 | 方法说明 |
| add() | 往集合中添加元素 |
| contains() | 判断集合中是否存在某元素 |
| remove() | 从集合中删除指定的元素 |
| clear() | 清除集合中所有元素 |
| size() | 获取集合中元素个数 |
| isEmpty() | 判断集合元素是否为空 |
| Iterator() | 返回元素的迭代器 |
public static void main(String[] args) {
// 创建存储字符串的HashSet集合
Set<String> objects = new HashSet<>();
// 往集合中添加元素
objects.add("123");
objects.add("456");
objects.add("789");
// 判断集合是否为空
boolean empty = objects.isEmpty();
System.out.println(empty);
// 判断集合是否包含元素123
boolean contains = objects.contains("123");
System.out.println(contains);
// 移除集合元素123
objects.remove("123");
System.out.println(objects);
// 获取迭代器,遍历集合所有元素
Iterator<String> iterator = objects.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
// 创建存储字符串的HashSet集合
Set<String> objects = new HashSet<>();
// 往集合中添加元素
objects.add("123");
objects.add("aa");
objects.add("a");
// 获取迭代器,遍历集合所有元素
Iterator<String> iterator = objects.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
// 创建存储字符串的HashSet集合
Set<String> objects = new HashSet<>();
// 往集合中添加元素
objects.add("ss");
objects.add("ss");
objects.add("how");
// 获取迭代器,遍历集合所有元素
Iterator<String> iterator = objects.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
HashSet还有一个子类LinkedList、LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的,也就是说当遍历集合LinkedHashSet集合里的元素时,集合将会按元素的添加顺序来访问集合里的元素。
输出集合里的元素时,元素顺序总是与添加顺序一致。但是LinkedHashSet依然是HashSet,因此它不允许集合重复。
无序不可重复的,但是存储的元素可以自动按照大小顺序排序(无序指的是:存进去的顺序和取出来的顺序不同。并且没有下标)
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet<Integer> nums = new TreeSet<>();
//向集合中添加元素
nums.add(5);
nums.add(2);
nums.add(15);
nums.add(-4);
//输出集合,可以看到元素已经处于排序状态
System.out.println(nums);//[-4, 2, 5, 15]
System.out.println("集合中的第一个元素:"+nums.first());//集合中的第一个元素:-4
System.out.println("集合中的最后一个元素:"+nums.last());//集合中的最后一个元素:15
System.out.println("集合小于4的子集,不包含4:"+nums.headSet(4));//集合小于4的子集,不包含4:[-4, 2]
System.out.println("集合大于5的子集:"+nums.tailSet(2));//集合大于5的子集:[2, 5, 15]
System.out.println("集合中大于等于-3,小于4的子集:"+nums.subSet(-3,4));//集合中大于等于-3,小于4的子集:[2]
}
Comparator comparator():如果TreeSet采用了定制顺序,则该方法返回定制排序所使用的Comparator,如果TreeSet采用自然排序,则返回null;
Object first():返回集合中的第一个元素;
Object last():返回集合中的最后一个元素;
Object lower(Object e):返回指定元素之前的元素。
Object higher(Object e):返回指定元素之后的元素。
SortedSet subSet(Object fromElement,Object toElement):返回此Set的子集合,含头不含尾;
SortedSet headSet(Object toElement):返回此Set的子集,由小于toElement的元素组成;
SortedSet tailSet(Object fromElement):返回此Set的子集,由大于fromElement的元素组成;
————————————————
版权声明:本文为CSDN博主「Mrkang1314」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mashaokang1314/article/details/83721792
}
```java
Comparator comparator():如果TreeSet采用了定制顺序,则该方法返回定制排序所使用的Comparator,如果TreeSet采用自然排序,则返回null;
Object first():返回集合中的第一个元素;
Object last():返回集合中的最后一个元素;
Object lower(Object e):返回指定元素之前的元素。
Object higher(Object e):返回指定元素之后的元素。
SortedSet subSet(Object fromElement,Object toElement):返回此Set的子集合,含头不含尾;
SortedSet headSet(Object toElement):返回此Set的子集,由小于toElement的元素组成;
SortedSet tailSet(Object fromElement):返回此Set的子集,由大于fromElement的元素组成;
java.util.Map接口中常用的方法:
Map和Collection没有继承关系
Map集合以key和value的方式存储数据:键值对
key和value都是引用数据类型
key和value都是存储对象的内存地址
key起到主导地位,value是key的一个附属品
HashMap允许key部分为null
package com.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/*
Map集合中常用的方法
V put(K key, V value)向Map集合中添加键值对
V 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集合
假设现在有一个Map集合,如下所示:
map1集合对象
key value
-------------------
1 zhangsan
2 lisi
3 wangwu
4 zhaoliu
Set set = map1.entrySet();
set集合对象
1=zhangsan
2=lisi
3=wangwu
4=zhaoliu
【注意:Map集合通过entrySet()方法转换成的这个Set集合,Set集合中元素的类型是Map.Entry<K,V>】
Map.Entry和String一样,都是一种类型的名字,只不过:Map.Entry是静态内部类,是Map中的静态内部类
*/
public class MapTest01 {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer,String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1,"zhangsan"); //1在这里进行了自动装箱
map.put(2,"lisi");
map.put(3,"wangwu");
map.put(4,"zhaoliu");
//通过key获取value
String value = map.get(2);
System.out.println(value);
//获取键值对的数量
System.out.println("键值对的数量:" + map.size()); //4
//通过key删除key-value
map.remove(2);
System.out.println("键值对的数量:" + map.size()); //3
//判断是否包含某个key
//contains方法底层调用的都是equals进行比对的,所以自定义的类型需要重写equals方法
System.out.println(map.containsKey(4)); //true
//判断是否包含某个value
System.out.println(map.containsValue("wangwu")); //true
//获取所有的value
Collection<String> values = map.values();
for (String s:values){
System.out.println(s);
}
//清空map集合
map.clear();
System.out.println("键值对的数量:" + map.size()); //0
//判断是否为空
System.out.println(map.isEmpty()); //true
}
}
package com.collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapTest02 {
public static void main(String[] args) {
//第一种方式:获取所有的key,通过遍历key,来遍历value
Map<Integer,String> map = new HashMap<>();
map.put(1,"zhangsan");
map.put(2,"lisi");
map.put(3,"wangwu");
map.put(4,"zhaoliu");
//遍历Map集合
//获取所有的key,所有的key是一个Set集合
Set<Integer> keys = map.keySet();
//遍历key,通过key获取value
//迭代器可以
Iterator<Integer> it = keys.iterator();
while (it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key + "=" + value);
/*
1=zhangsan
2=lisi
3=wangwu
4=zhaoliu
*/
}
//foreach也可以
for (Integer key:keys){
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();
//遍历Set集合,每一次取出一个Node
//迭代器
Iterator<Map.Entry<Integer,String>> it2 = set.iterator();
while (it2.hasNext()){
Map.Entry<Integer,String> node = it2.next();
Integer key = node.getKey();
String value = node.getValue();
System.out.println(key + "=" + value);
}
//foreach方式
//这种方式效率比较高,因为获取key和value都是直接从node对象中获取的属性值
//这种方式适合大数据量
for (Map.Entry<Integer,String> node : set){
System.out.println(node.getKey() + "=" + node.getValue());
}
}
}
HashMap集合:
public class HashMap{
//HashMap底层实际上就是一个数组(一维数组)
Node<K,V> table;
//静态内部类HashMap.Node
static class Node<K,V> {
final int hash; //哈希值(哈希值是key的hashCode()方法执行结果。hash值通过哈希函数/算法,可以转化存储成数组下标)
final K key; //存储到Map集合中的那个key
V value; //存储到Map集合中的那个value
Node<K,V> next; //下一个节点的内存地址
}
package com.collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest01 {
public static void main(String[] args) {
//测试HashMap集合key部分的元素特点
//Integer是key,它的hashCode和equals都重写了
Map<Integer,String> map = new HashMap<>();
map.put(1111,"zhangsan");
map.put(6666,"lisi");
map.put(7777,"wangwu");
map.put(2222,"zhaoliu");
map.put(2222,"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());
}
}
}
package com.bean;
import java.util.HashSet;
import java.util.Set;
/*
1. 向Map集合中存,以及从Map集合中取,都是县调用key的hashCode方法,然后在调用equals方法
equals方法有可能调用,也有可能不会调用
2. 注意:如果一个类的equals方法重写了,那么hashCode()方法必须重写,
并且equals方法返回如果是true,hashCode()方法返回的值必须一样
equals方法返回true表示两个对象相同,在同一个单向链表上比较
那么对于同一个单向链表上的节点来说,他们的哈希值都是相同的
所有hashCode()方法的返回值也应该是相同的
3. 放在hashCode集合key部分,以及放在hashSet集合中的元素,需要同时重写hashCode方法和equals方法
*/
public class HashMapTest02 {
public static void main(String[] args) {
Student s1 = new Student("zhangsan");
Student s2 = new Student("zhangsan");
//重写equals方法之前是false
System.out.println(s1.equals(s2)); //false
//重写equals方法之后是true
System.out.println(s1.equals(s2));
System.out.println("s1的hashCode="+s1.hashCode()); //22307196
System.out.println("s2的hashCode="+s2.hashCode()); //10568834
//s1.equals(s2)已经是true了,表示s1和s2是一样的,那么王hashCode集合中方法的话,
//按说只能放进去一个(HashSet集合特点无序不可重复)
Set<Student> students = new HashSet<>();
students.add(s1);
students.add(s2);
System.out.println(students.size()); //这个结果按说应该是1,但是结果为2
//重写equals和hashCode之后hashCode都为-1432604525
}
}
package com.bean;
import java.util.Objects;
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//重写equals (如果名字一样,表示同一个学生)
/*public boolean equals(Object object){
if (object == null || !(object instanceof Student)) return false;
if (object == this) return true;
Student student = (Student)object;
if (this.name.equals(student.name)) return true;
return false;
}*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
package com.bean;
import java.util.Hashtable;
import java.util.Map;
/*
Hashtable的key和value都不能为null的
HashMap集合的key和value都是可以为null的
Hashtable方法都带有synchronized:线程安全的
线程安全有其他的方案,这个Hashtable对线程的处理导致效率较低,使用少
Hashtable和HashMap一样,底层都是哈希表数据结构
*/
public class HashTableTest01 {
public static void main(String[] args) {
Map map = new Hashtable();
map.put(null,"123"); //出现异常
}
}
package com.collection;
import java.util.Properties;
/*
掌握Properties属性类对象的相关方法
Properties是一个Map集合,继承Hashtable,Properties的key和value都是String类型
Properties被称为属性类对象
Properties是线程安全的
*/
public class PropertiesTest01 {
public static void main(String[] args) {
//创建一个Properties对象
Properties properties = new Properties();
//需要掌握Properties的两个方法,一个存,一个取
properties.setProperty("url","jdbc:mysql//localhost:3306");
properties.setProperty("username","root");
properties.setProperty("password","123");
// 通过key获取value
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
}
package com.collection;
import java.util.TreeSet;
/*
*/
public class TreeSetTest02 {
public static void main(String[] args) {
//创建一个TreeSet集合
TreeSet<String> ts = new TreeSet<>();
//添加String
ts.add("zhangsan");
ts.add("lisi");
ts.add("wangwu");
//遍历
for (String s:ts){
//安装字典顺序,升序
System.out.println(s);
}
TreeSet<Integer> ts2 = new TreeSet<>();
ts2.add(100);
ts2.add(200);
ts2.add(900);
ts2.add(10);
ts2.add(150);
for (Integer elt:ts2){
System.out.println(elt);
}
}
}
lisi
wangwu
zhangsan
10
100
150
200
900
package com.collection;
import java.util.TreeSet;
public class TreeSetTest03 {
public static void main(String[] args) {
Customer c1 = new Customer(32);
Customer c2 = new Customer(20);
Customer c3 = new Customer(30);
Customer c4 = new Customer(25);
//创建TreeSet集合
TreeSet<Customer> customers = new TreeSet<>();
//添加元素
customers.add(c1);
customers.add(c2);
customers.add(c3);
customers.add(c4);
//遍历
for (Customer c : customers){
System.out.println(c);
}
}
}
/*
放在TreeSet集合中的元素需要实现java.lang.Comparable接口
并且实现compareTo方法,equals可以不写
*/
class Customer implements Comparable<Customer>{
int age;
public Customer(int age) {
this.age = age;
}
//需要在这个方法中编写比较的逻辑:按照什么进行比较
//k.compareTo(t.key)
//拿着参数k和集合中每一个k进行比较,返回值可能是><=0
@Override
public int compareTo(Customer c) { //c1.compareTo(c2);
//this是c1
//c是c2
//c1和c2比较的时候,就是this和c比较
/*int age1 = this.age;
int age2 = c.age;
if (age1 == age2){
return 0;
} else if (age1>age2){
return -1;
} else {
return 1;
}*/
return this.age - c.age; //=0 >0 <0
}
public String toString(){
return "Customer[age="+age+"]";
}
}
Customer[age=20]
Customer[age=25]
Customer[age=30]
Customer[age=32]
package com.collection;
import java.util.TreeSet;
/*
先按照年龄升序,如果年龄一样再按照姓名升序
*/
public class TreeSetTest04 {
public static void main(String[] args) {
TreeSet<Vip> vips = new TreeSet<>();
vips.add(new Vip("zhangsan",20));
vips.add(new Vip("zhangsi",20));
vips.add(new Vip("lisi",20));
vips.add(new Vip("king",18));
for (Vip vip : vips){
System.out.println(vip);
}
}
}
class Vip implements Comparable<Vip>{
String name;
int age;
public Vip(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Vip{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Vip v) {
if (this.age == v.age) {
//年龄相同按照名字排序
//姓名是String类型,可以直接比较,调用compareTo来完成比较
return this.name.compareTo(v.name);
} else {
return this.age - v.age;
}
}
}
Vip{name='king', age=18}
Vip{name='lisi', age=20}
Vip{name='zhangsan', age=20}
Vip{name='zhangsi', age=20}
从API当中我们可以看出,public final class System exends Object。System类包含一些有用的字段和方法。这些字段和类都被static修饰了,说明他们都不能被实例化。
在System类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的使用方法。
字段摘要
static PrintStream err ”标准“输入错误流
static InputStream in ”标准“输入流
static PrintStream out ”标准“输出流
这里仅介绍几个常用的:
– static long currentTimeMillis()
// 返回以毫秒为单位的当前时间。 1970 年 1 月 1
– arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
–exit(int status)
//终止当前正在运行的 Java 虚拟机,非 0 的状态码表示异常终止。
–gc(); //唤起垃圾回收器
–static Map<String,String> getenv()
public class Test6 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();// 取得计算开始时的时间
@SuppressWarnings("unused")
int sum = 0;// 声明变量并初始化
for (int i = 0; i < 1000000000; i++) { // 进行累加
sum+=i;
}
long endTime = System.currentTimeMillis();// 取得计算结束时间
// 计算所花费的时间
System.out.println("累加所花费的时间" + (endTime - startTime) + "毫秒");
}
}
除此之外还有很多有用的方法,应用代码如下:
import java.util.Properties;
import java.util.Set;
public class Test1 {
public static void main(String[] args) {
Properties p = System.getProperties();//列出系统全部属性
Set<Object> set = p.keySet();
for (Object key : set) { //利用增强for遍历
System.out.println(key + ":" + p.get(key));
}
System.out.println("=====分割线1=====");
String p2 = System.getProperty("os.name");//查找
System.out.println(p2);
System.out.println("=====分割线2=====");
System.setProperty("Mykey", "zhouzhou的系统");//自定义系统名称属性
System.out.println("Mykey");
}
}
打印结果:
java.runtime.name:Java(TM) SE Runtime Environment
sun.boot.library.path:C:\Program Files\Java\jdk1.7.0_75\jre\bin
java.vm.version:24.75-b04
java.vm.vendor:Oracle Corporation
java.vendor.url:http://java.oracle.com/
path.separator:;
java.vm.name:Java HotSpot(TM) Client VM
file.encoding.pkg:sun.io
user.country:CN
user.script:
sun.java.launcher:SUN_STANDARD
sun.os.patch.level:
java.vm.specification.name:Java Virtual Machine Specification
user.dir:E:\ClassC
java.runtime.version:1.7.0_75-b13
java.awt.graphicsenv:sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs:C:\Program Files\Java\jdk1.7.0_75\jre\lib\endorsed
os.arch:x86
java.io.tmpdir:C:\Users\win7\AppData\Local\Temp\
line.separator:
可以看出,System类本身提供的静态属性都是与IO操作有关。比如,gc();
代码实例:
public class Test7 {
private String name;
private int age;
public Test7(String name, int age) {
this.age = age;
this.name = name;
}
public String toString() {
return "姓名:" + this.name + " 年龄:" + this.age;
}
public void finalize() throws Throwable { // 释放空间
System.out.println("对象被释放==" + this);
}
}
Java 中的 Object 方法在面试中是一个非常高频的点,毕竟 Object 是所有类的“老祖宗”。Java 中所有的类都有一个共同的祖先 Object 类,子类都会继承所有 Object 类中的 public 方法。
final 方法、获取对象的运行时 class 对象,class 对象就是描述对象所属类的对象。这个方法通常是和 Java 反射机制搭配使用的。
该方法主要用于获取对象的散列值。Object 中该方法默认返回的是对象的堆内存地址。
该方法用于比较两个对象,如果这两个对象引用指向的是同一个对象,那么返回 true,否则返回 false。一般 equals 和 == 是不一样的,但是在 Object 中两者是一样的。子类一般都要重写这个方法。
该方法是保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。
默认的 clone 方法是浅拷贝。所谓浅拷贝,指的是对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存。深拷贝则是会连引用的对象也重新创建。
返回一个 String 对象,一般子类都有覆盖。默认返回格式如下:对象的 class 名称 + @ + hashCode 的十六进制字符串。
final 方法,主要用于唤醒在该对象上等待的某个线程。
final 方法,主要用于唤醒在该对象上等待的所有线程。
wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait() 方法一直等待,直到获得锁或者被中断。wait(long timeout) 设定一个超时间隔,如果在规定时间内没有获得锁就返回。欢迎大家关注我的公种浩【程序员追风】,文章都会在里面更新,整理的资料也会放在里面。
**wait(long timeout, int nanos) 方法public final void wait(long timeout, int nanos) throws InterruptedException {**
```java
if (timeout
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
1、String表示字符串类型,属于 引用数据类型,不属于基本数据类型。
2、在java中随便使用 双引号括起来 的都是String对象。
例如:“abc”,“def”,“hello world!”,这是3个String对象。
3、java中规定,双引号括起来的字符串,是 不可变 的,也就是说"abc"自出生到最终死亡,不可变,不能变成"abcd",也不能变成"ab"
4、在JDK当中双引号括起来的字符串,例如:“abc” "def"都是直接存储在“方法区”的“字符串常量池”当中的。
5、为什么SUN公司把字符串存储在一个“字符串常量池”当中呢?
因为字符串在实际的开发中使用太频繁。为了执行效率,所以把字符串放到了方法区的字符串常量池当中。
public class StringTest01 {
public static void main(String[] args) {
// 这两行代码表示底层创建了3个字符串对象,都在字符串常量池当中。
String s1 = "abcdef";
String s2 = "abcdef" + "xy";
// 分析:这是使用new的方式创建的字符串对象。这个代码中的"xy"是从哪里来的?
// 凡是双引号括起来的都在字符串常量池中有一份。
// new对象的时候一定在堆内存当中开辟空间。
String s3 = new String("xy");
}
}
public class StringTest02 {
public static void main(String[] args) {
String s1 = "hello";
// "hello"是存储在方法区的字符串常量池当中
// 所以这个"hello"不会新建。(因为这个对象已经存在了!)
String s2 = "hello";
// == 双等号比较的是变量中保存的内存地址
System.out.println(s1 == s2); // true
String x = new String("xyz");
String y = new String("xyz");
// == 双等号比较的是变量中保存的内存地址
System.out.println(x == y); //false
}
}
字符串对象之间的比较不能使用“== ”,"=="不保险。应该调用String类的equals方法
String k = new String("testString");
//String k = null;
// "testString"这个字符串可以后面加"."呢?
// 因为"testString"是一个String字符串对象。只要是对象都能调用方法。
System.out.println("testString".equals(k)); // 建议使用这种方式,因为这个可以避免空指针异常。
System.out.println(k.equals("testString")); // 存在空指针异常的风险。不建议这样写。
**
**
二、构造方法
构造方法名 eg.
String s = “xxx” 最常用
String(String original) String(“xxx”)
String(char数组)
String(char数组,起始下标,长度)
String(byte数组)
String(byte数组,起始下标,长度)
String(StringBuffer buffer)
String(StringBuilder builder)
class StringTest{
public static void main(String[] args) {
//最常用的方式
String s1 = "我是中国人";
System.out.println(s1);//我是中果人
String s2 = new String("我是中国人");
System.out.println(s2);//我是中果人
char[] c = {'我' , '是', '中', '果', '人'};
String s3 = new String(c);
System.out.println(s3);//我是中果人
String s4 = new String(c, 2, 3);
System.out.println(s4);//中果人
byte[] b = {65, 66 ,67, 68};
String s5 = new String(b);
System.out.println(s5);//ABCD
String s6 = new String(b, 1, 2);
System.out.println(s6);//BC
StringBuffer sb1 = new StringBuffer("我是福建人");
String s7 = new String(sb1);
System.out.println(s7);//我是福建人
StringBuilder sb2 = new StringBuilder("我是厦门人");
String s8 = new String(sb2);
System.out.println(s8);//我是厦门人
}
}
class StringTest{
public static void main(String[] args) {
String s1 = "hello world";
System.out.println(s1.charAt(6));//w
String s2 = "abc";
String s3 = "xyz";
String s4 = "xyz";
System.out.println(s2.compareTo(s3));//-23
System.out.println(s3.compareTo(s4));//0
System.out.println(s4.compareTo(s1));//16
System.out.println(s2.equals(s3));//false
System.out.println(s1.endsWith("world"));//true
System.out.println(s1.endsWith("t"));//false
String s5 = "HELLO worLD";
System.out.println(s1.equalsIgnoreCase(s5));//true
byte[] b = s1.getBytes();
System.out.println(Arrays.toString(b));//[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
System.out.println(s1.indexOf("world"));//6
System.out.println(s1.indexOf("h"));//0
System.out.println(s1.isEmpty());//false
System.out.println(s1.length());//11
String s6 = "javapythonc++cphpjavapython";
System.out.println(s6.lastIndexOf("java"));//17
System.out.println(s6.lastIndexOf("h"));//24
String s7 = "name=zhangsan&age=18&sex=男";
String newS7 = s7.replace("&", ";");
System.out.println(newS7);//name=zhangsan;age=18;sex=男
String[] splitS7 = s7.split("&");
System.out.println(Arrays.toString(splitS7));//[name=zhangsan, age=18, sex=男]
System.out.println(s6.startsWith("java"));//true
System.out.println(s6.startsWith("python"));//false
System.out.println(s6.substring(10));//c++cphpjavapython
System.out.println(s6.substring(10, 13));//c++
char[] charS6 = s6.toCharArray();
System.out.println(Arrays.toString(charS6));//[j, a, v, a, p, y, t, h, o, n, c, +, +, c, p, h, p, j, a, v, a, p, y, t, h, o, n]
System.out.println(s6.toUpperCase());//JAVAPYTHONC++CPHPJAVAPYTHON
System.out.println(s5.toLowerCase());//hello world
String s8 = " 你 好 世 界 ";
System.out.println(s8.trim());//你 好 世 界
System.out.println("------------------------------");
System.out.println(String.valueOf(123));//123
System.out.println(String.valueOf(3.14));//3.14
System.out.println(String.valueOf(true));//true
System.out.println(String.valueOf(new Object()));//java.lang.Object@4554617c
//valueOf会自动调用toString()方法
}
}
StringBuilder builder = new StringBuilder();
StringBuilder builder = new StringBuilder("abc");
StringBuilder builder = new StringBuilder(初始长度);
Object
String
StringBuffer
CharSequence
char[]
boolean
char
int
long
float
double
public class Main {
public static void main(String[] args) {
StringBuilder s = new StringBuilder();
s.append("nimabi").append("草拟吗").append("over");
System.out.println(s);
}
}
public class Main {
public static void main(String[] args) {
StringBuilder s = new StringBuilder("helloWorld");
s.insert(2,"ttt");//向索引为2的位置添加ttt字符串
System.out.println(s);
}
}
deleteCharAt(int index )删除指定位置的元素
4. 改
replace(start,end, string) 将[start, end) 的元素修改为string
public StringBuffer() 构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。
public StringBuffer(int capacity) 指定容量的字符串缓冲区对象
public StringBuffer(String str) 指定字符串内容的字符串缓冲区对象
初始化
StringBuffer a=new StringBuffer("abc");
a.append("b");
String a="acd";
StringBuffer b= new StringBuffer(a);
b.insert(1,"b");
System.out.println(b);
输出: cad
StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
java.util.Data类,表示特定的瞬间。精确到毫秒。
简单来说:使用无参构造,可以自动设置当前系统时间的毫秒时刻;指定Long类型的构造参数。可以自定义毫秒时刻。例如:
System.out.println(new Date());——>当前时间
System.out.println(new Data(0L));——>把当前的毫秒值转成日期对象。
Tips:在使用println方法的时候,会自动调用Data类中的toString方法。Data类对Object类中的toString方法进行了覆盖重写,所以结果为指定格式的字符串。
常用方法
public Long getTime():把日期对象转换成对应的时间毫秒值。
DataFromat类
java.text.DateFromat是日期/时间格式化子类的抽象类。我们可以通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Data对象与String对象之间进行来回转换。
格式化:按照指定的格式。从Data对象转换为String对象。
解析:按照指定的格式,从String对象转换为Data对象。
构造方法
由于DataFromat为抽象类,不能直接使用,所以需要常用的子类。
java.text.SimpleDataFormat。这个类需要一个模式(格式),来指定格式化或解析的标准。构造方法为:
public SimpleDataFormat(String pattern):用给定的模式和默认语言环境的日期格式符号构造SimpleDataFormat。
参数pattern是一个字符串,代表日期时间的自定义格式、
格式规则
常用的格式规则为:
| 标识字母(区分大小写)| 含义|
| 标识字母(区分大小写) | 含义 |
|---|---|
| y | l年 |
| y | 年 |
| M | 月 |
| d | 日 |
| H | 时 |
| m | 分 |
| s | 秒 |
创建SimpleDataFormat对象的代码如:
DataFormat format=new SimpleDataFormat(“yyyy-MM-dd HH:mm:ss”);
常用方法
public String format(Data data):将Data对象格式化为字符串。
public Data parse(String source):将字符串解析为Data对象。
format方法
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
把Date对象转换成String
*/
public class Demo03DateFormatMethod {
public static void main(String[] args) {
Date date = new Date();
// 创建日期格式化对象,在获取格式化对象时可以指定风格
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
String str = df.format(date);
System.out.println(str); // 2008年1月23日
}
}
parse方法
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
把String转换成Date对象
*/
public class Demo04DateFormatMethod {
public static void main(String[] args) throws ParseException {
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
String str = "2018年12月11日";
Date date = df.parse(str);
System.out.println(date); // Tue Dec 11 00:00:00 CST 2018
}
}
java.util.Calendar类是日历类,在Date后出现,替换掉了血多Date的方法。该类将所有可能用到的时间信息封装为静态成员变量,方便获取。日历类就是方便获取各个时间属性的。
获取方法
Calender类为抽象类,由于语言敏感性,Calendar类在创建对象时并非直接创建,而是通过静态方法创建。返回子类对象,如下:
public static Calendar getInstance():使用默认时区和语言环境获得一个一个日历
import java.util.Calendar;
public class Demo06CalendarInit {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
}
}
get方法用来获取指定字段的值,set方法用来设置指定字段的值:
import java.util.Calendar;
public class CalendarUtil {
public static void main(String[] args) {
// 创建Calendar对象
Calendar cal = Calendar.getInstance();
// 设置年
int year = cal.get(Calendar.YEAR);
// 设置月
int month = cal.get(Calendar.MONTH) + 1;
// 设置日
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
System.out.print(year + "年" + month + "月" + dayOfMonth + "日");
}
}
import java.util.Calendar;
public class Demo07CalendarMethod {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2020);
System.out.print(year + "年" + month + "月" + dayOfMonth + "日"); // 2020年1月17日
}
}
add方法可以对指定日历字段的值进行加减操作,如果第二个参数为整数则加上偏移量,如果为负数则减去偏移量。
import java.util.Calendar;
public class Demo08CalendarMethod {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.print(year + "年" + month + "月" + dayOfMonth + "日"); // 2018年1月17日
// 使用add方法
cal.add(Calendar.DAY_OF_MONTH, 2); // 加2天
cal.add(Calendar.YEAR, -3); // 减3年
System.out.print(year + "年" + month + "月" + dayOfMonth + "日"); // 2015年1月18日;
}
}
Calendar中的getTime方法并不是获取毫秒时刻,而是拿到对应的Date对象。
import java.util.Calendar;
import java.util.Date;
public class Demo09CalendarMethod {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
System.out.println(date); // Tue Jan 16 16:03:09 CST 2018
}
}