这篇文章主要介绍了java集合的实现代码怎么写的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java集合的实现代码怎么写文章都会有所收获,下面我们一起来看看吧。
public class HashMapDemo {
private Map map = null;
public void init() {
map = new HashMap();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");
System.out.println(map);
}
// 添加元素
public void testPut() {
// V put(K key, V value) :把指定的key和value添加到集合中
map.put("a1", "aaa");
map.put("b1", "bbb");
map.put("c1", "ccc");
System.out.println(map);
// void putAll(Map<? extends K,? extends V>m) :把指定集合添加集合中
Map map1 = new HashMap();
map1.put("e", "eee");
map1.put("f", "fff");
map.putAll(map1);
System.out.println(map);
// default V putIfAbsent(K key, V value) :如果key不存在就添加
map.putIfAbsent("a", "hello");
System.out.println(map);
map.putIfAbsent("g", "ggg");
System.out.println(map);
}
// 修改元素
public void testModify() {
// V put(K key, V value) :把集合中指定key的值修改为指定的值
map.put("a", "hello");
map.put("a", "world");
System.out.println(map);
// 说明,当key相同时,后面的值会覆盖前面的值。
// default V replace(K key, V value) :根据key来替换值,而不做增加操作
Object replace = map.replace("b1", "java");
System.out.println(replace);
System.out.println(map);
//default boolean replace(K key, V oldValue,V newValue)
}
// 删除元素
public void testRemove() {
// V remove(Object key) :根据指定key删除集合中对应的值
Object c = map.remove("c");
System.out.println(c);
System.out.println(map);
// default boolean remove(Object key, Objectvalue) :根据key和value进行删除
map.remove("b", "bbb1");
System.out.println(map);
// void clear() :清空集合中所有元素
map.clear();
System.out.println(map);
}
// 判断元素
public void testJudge() {
// boolean isEmpty() :判断集合是否为空,如果是返回true,否则返回false
System.out.println(map.isEmpty());
// boolean containsKey(Object key) :判断集合中是否包含指定的key,包含返回true,否则返回false
boolean flag = map.containsKey("a");
System.out.println(flag); // true
flag = map.containsKey("a1");
System.out.println(flag); // false
// boolean containsValue(Object value) :判断集合中是否包含指定的value,包含返回true,否则返回false
flag = map.containsValue("aaa");
System.out.println(flag); // true
flag = map.containsValue("aaa1");
System.out.println(flag); // false
}
// 获取元素
public void testGet() {
// int size() :返回集合的元素个数
int size = map.size();
System.out.println(size);
// V get(Object key) :根据Key获取值,如果找到就返回对应的值,否则返回null
Object val = map.get("a");
System.out.println(val);
val = map.get("a1");
System.out.println(val); // null
// default V getOrDefault(Object key, VdefaultValue) :根据Key获取值,如果key不存在,则返回默认值
val = map.getOrDefault("a1", "hello");
System.out.println(val);
// Collection<V> values() :返回集合中所有的Value
Collection values = map.values();
for (Object value : values) {
System.out.println(value);
}
// Set<K> keySet() :返回集合中所有的Key
Set set = map.keySet();
for (Object o : set) {
System.out.println(o);
}
}
// 迭代元素
public void testIterator() {
// 第一种:通过key获取值的方式
Set keySet = map.keySet();
Iterator it = keySet.iterator();
while (it.hasNext()) {
Object key = it.next();
Object val = map.get(key);
System.out.println(key + "=" + val);
}
System.out.println("------------------------ ");
// 第二种:使用for循环
for (Object key : map.keySet()) {
System.out.println(key + "=" +
map.get(key));
}
System.out.println("------------------------ ");
// 第三种:使用Map接口中的内部类来完成,在框架中大量使用
Set entrySet = map.entrySet();
for (Object obj : entrySet) {
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey() + "=" +
entry.getValue());
}
}
}
说明:在HashMap中键-值允许为空,但键唯一,值可重复。hashMap不是线程安全的。
是一个有序的集合,默认使用的是自然排序方式。
public class Person implements Comparable {
private String name;
private int age;
@Override
public int compareTo(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return this.age - p.age;
}
return 0;
}
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试
public class TeeMapDemo {
@Test
public void testInteger() {
TreeMap tm = new TreeMap();
tm.put(3, 333);
tm.put(2, 222);
tm.put(11, 111);
tm.put(2, 222);
System.out.println(tm);
}
@Test
public void testString() {
TreeMap tm = new TreeMap();
tm.put("hello", "hello");
tm.put("world", "world");
tm.put("about", "");
tm.put("abstract", "");
System.out.println(tm);
}
@Test
public void testPerson() {
TreeMap tm = new TreeMap(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o2
instanceof Person) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
return p1.getAge() - p2.getAge();
}
return 0;
}
});
tm.put(new Person("张三",18), null);
tm.put(new Person("李四",17), null);
System.out.println(tm);
}
}
说明:从上面的代码可以发现,TreeMap的使用和TreeSet的使用非常相似,观察HashSet集合的源代码可以看出,当创建 HashSet集合时,其实是底层使用的是HashMap。
public HashSet() {
map = new HashMap<>();
}
HashSet实际上存的是HashMap的Key。
在Map集合中我们介绍了HashMap
,TreeMap
,在多线程的情况下这些集合都不是线程安全的,因此可能出现线程安全的问题。
在Java中Hashtable是一种线程安全的HashMap
,Hashtable
在方法上与HashMap
并无区别,仅仅只是在方法使用了synchronized
以此来达到线程安全的目的,我们观察Hashtable的源码。
public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
return null;
}
以上是Hashtable的get源码,可以看出它仅仅只是在方法上添加了锁,这大大降低了线程的执行效率,以牺牲效率的形式来达到目的,这显然不是我们在实际中想要的,因此我们需要一种既能在线程安全方面有保障,在效率上还可以的方法。
ConcurrentHashMap采用的是分段锁的原理,我们观察源码。
public V put(K key, V value) {
return putVal(key, value, false);
}
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
for (Node<K,V> e = f;; ++binCount) {
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
Node<K,V> pred = e;
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
从源码中可以看出ConcurrentHashMap
仅仅是在当有线程去操作当前数据的时候添加了锁,因此效率大大提高了。
在线程安全的情况下提高了效率。
关于“java集合的实现代码怎么写”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“java集合的实现代码怎么写”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4592422/blog/4435252