持有对象(集合)

2024-04-28 10:58
文章标签 对象 集合 持有

本文主要是介绍持有对象(集合),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

添加一组元素

java.util包中的ArraysCollections类中都有很多实用方法,可以在一个Collection中添加一组元素。Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List集合。Collections.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分隔的列表,将元素添加到Collection中。

package com.huangfei.thinking.holding;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;public class AddingGroups {public static void main(String[] args) {/*** Collection的构造器可以接受另一个Collection,用它来将自身初始化,因此你可以使用Arrays.asList()来为这个构造器产生输入。* 但是,Collection.addAll()方法运行起来要快得多,而且构建一个不包含元素的Collection,然后调用Collection.addAll()* 这种方式很方便,因此它是首选方式。*/Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));Integer[] moreInts = {6, 7 ,8 , 9 , 10};collection.addAll(Arrays.asList(moreInts));/*** Collection.addAll()成员方法只能接受另一个Collection对象作为参数,因此它不如Arrays.asList()* 和Collections.addAll()灵活,这两个方法使用的都是可变参数列表。*/Collections.addAll(collection, 11, 12, 13, 14, 15);Collections.addAll(collection, moreInts);/*** 你可以直接使用Arrays.asList()的输出,将其当作List,但是这种情况下,其底层表示的是数组,因此不能调整尺寸。如果你试图用add()* 或delete()方法在这种列表中添加或删除元素,就有可能会引发去改变数组尺寸的尝试,因此你将在运行时获得“UnsupportedOperationException”* (不支持的操作)的错误。*/List<Integer> list = Arrays.asList(16, 17, 18,19, 20);list.set(1, 99);//list.add(21);}}

Arrays.asList()方法的限制是它对所产生的List的类型做出了最理想的假设,而并没有注意你对它会赋予什么样的类型。有时就会引发问题:

package com.huangfei.thinkinginjava.holding;import java.util.*;class Snow {}
class Powder extends Snow {}
class Light extends Powder {}
class Heavy extends Powder {}
class Crusty extends Snow {}
class Slush extends Snow {}public class AsListInference {public static void main(String[] args) {List<Snow> snow1 = Arrays.asList(new Crusty(), new Slush(), new Powder());/*** 当试图创建snow2时,Arrays.asList()中只有Power类型,因此它会创建List<Powder>而不是List<Snow>。*/// List<Snow> snow2 = Arrays.asList(new Light(), new Heavy());/*** Collections.addAll()工作的很好,因为它从第一个参数中了解到了目标类型是什么。*/List<Snow> snow3 = new ArrayList<Snow>();Collections.addAll(snow3, new Light(), new Heavy());/*** 可以在Arrays.asList()中间插入一条“线索”,以告诉编译器对于由Arrays.asList()产生的List类型,实际的目标类型应该是什么,这* 称为显示类型参数说明。*/List<Snow> snow4 = Arrays.<Snow>asList(new Light(), new Heavy());}
}

List

package com.huangfei.thinkinginjava.holding;public class Pet {private String name;public Pet(String name){this.name = name;}@Overridepublic String toString() {return name;}@Overridepublic boolean equals(Object obj) {return super.equals(obj);}}
package com.huangfei.thinkinginjava.holding;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class ListFeatures {public static void main(String[] args) {List<Pet> pets = new ArrayList<Pet>();pets.addAll(Arrays.asList(new Pet("Rat"), new Pet("Manx"), new Pet("Mutt"), new Pet("Pug")));System.out.println("1:" + pets);Pet pet = new Pet("Hamster");pets.add(pet);System.out.println("2:" + pets);/*** 当确定一个元素是否属于某个List,发现某个元素的索引,以及从某个List中移除一个元素时,都会用到equals()方法(它是根类Object的一部分)。* 不同的类,equals()的定义可能有所不同。例如两个String只有在内容完全一样的情况下才会是等价的,因此必须意识到List的行为根据* equals()的行为而有所变化。*/System.out.println("3:" + pets.contains(pet));int index = pets.indexOf(pet);System.out.println("4:" + pet + " " + index);pets.remove(pet);/*** subList()方法允许你很容易地从较大的列表中创建一个片段,而将其结果传递给这个较大的列表的containsAll()方法时,很自然的会得到* true。我们从6中注意到顺序并不重要,在sub上调用Collections.shuffle()方法,不会影响containsAll()结果。subList()* 所产生的列表的幕后是初始化列表,因此,对所返回的列表的修改都会反映到初始列表中,反之亦然(7中显示的结果很好的证明了这一点)。*/List<Pet> sub = pets.subList(1, 4);System.out.println("sublist:" + sub);System.out.println("5:" + pets.containsAll(sub));Collections.shuffle(sub);System.out.println("shuffle sublist:" + sub);System.out.println("6:" + pets.containsAll(sub));System.out.println("7:" + pets);/*** retainAll()方法是一种有效的“交集”操作,在本例中,它保留了所有同时在copy和sub中的元素。请再次注意,所产生的行为依赖于equals()方法*/List<Pet> copy = new ArrayList<Pet>(pets);sub = Arrays.asList(pets.get(0), pets.get(2));System.out.println("sub:" + sub);copy.retainAll(sub);System.out.println("copy:" + copy);/*** 通过toArray()方法,可以将任意的Collection转换为一个数组。这是一个重载方法,其无参数版本返回的是Object数组,但是如果你向这个重载版本* 传递目标类型的数据,那么它将产生指定类型的数据(假设它能通过类型检查)。如果参数数组太小,存放不下List中的所有元素(就像本例),toArray()方法* 将创建一个具有合适尺寸的数组。*/Object[] o = pets.toArray();Pet[] pa = pets.toArray(new Pet[0]);/*** 方法asList()和subList()返回不可变List,因为它们是由底层数组和列表“支持”。如果您的结构修改我们在已被接受的部分中所做的备份列表,您可以得到一个并发的修改例外。* 因此,程序在子列表上运行支持的列表。或者,通过创建单独的副本来避免错误返回子列表并将其用作removeAll()的参数。*/Pet[] petArray = new Pet[10];for (int i = 0; i < petArray.length; i++) {petArray[i] = new Pet(i + "");}//List<Pet> petList = Arrays.asList(petArray);List<Pet> petList = new ArrayList<Pet>(Arrays.asList(petArray));System.out.println("petList:" + petList);List<Pet> subList = petList.subList(petList.size() / 4, petList.size() / 2);System.out.println("subList:" + subList);//如果支持列表在结构上修改,子列表的语义就会被取消。//petList.removeAll(subList);subList.clear();System.out.println("petList:" + petList);System.out.println("subList:" + subList);}}//output
1:[Rat, Manx, Mutt, Pug]
2:[Rat, Manx, Mutt, Pug, Hamster]
3:true
4:Hamster 4
sublist:[Manx, Mutt, Pug]
5:true
shuffle sublist:[Mutt, Manx, Pug]
6:true
7:[Rat, Mutt, Manx, Pug]
sub:[Rat, Manx]
copy:[Rat, Manx]
petList:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
subList:[2, 3, 4]
petList:[0, 1, 5, 6, 7, 8, 9]
subList:[]

ListIterator

package com.huangfei.thinkinginjava.holding;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;public class ListIteration {public static void main(String[] args) {List<Pet> pets = new ArrayList<Pet>();pets.addAll(Arrays.asList(new Pet("Rat"), new Pet("Manx"), new Pet("Mutt"), new Pet("Pug")));/*** ListIterator只能用于各种List类的访问,ListIterator可以双向移动,并且可以产生相对于迭代器在列表中指向的当前位置的前一个和* 后一个元素的索引,并且可以使用set()替换它访问过的最后一个元素,而且还可以通过调用listIterator(n)方法创建一个一开始就指向列表* 索引为n的元素处的ListIterator。*/ListIterator<Pet> lt = pets.listIterator();while(lt.hasNext()){System.out.print(lt.next() + ", " + lt.nextIndex() + ", " + lt.previousIndex()+ "; ");}System.out.println();while(lt.hasPrevious()){System.out.print(lt.previous() + " ");}System.out.println();System.out.println(pets);lt = pets.listIterator(2);while(lt.hasNext()){lt.next();lt.set(new Pet("Hamster"));}System.out.println(pets);}}
//output
Rat, 1, 0; Manx, 2, 1; Mutt, 3, 2; Pug, 4, 3; 
Pug Mutt Manx Rat 
[Rat, Manx, Mutt, Pug]
[Rat, Manx, Hamster, Hamster]

LinkedList

package com.huangfei.thinkinginjava.holding;import java.util.Arrays;
import java.util.LinkedList;public class LinkedListIteration {public static void main(String[] args) {LinkedList<Pet> pets = new LinkedList<Pet>();pets.addAll(Arrays.asList(new Pet("Rat"), new Pet("Manx"), new Pet("Mutt"), new Pet("Pug")));System.out.println(pets);/*** getFirst()和element()完全一样,他们都返回列表的头(第一个元素),而并不移除它,如果List为空,则抛出NoSuchElementException。* peek()方法与这两个方法只是稍有差异,它在列表为空的时候返回null。*/System.out.println("pets.getFirst():" + pets.getFirst());System.out.println("pets.element():" + pets.element());System.out.println("pets.peek():" + pets.peek());/*** remove()与removeFirst())也完全是一样的,它们移除并返回列表的头,而在列表为空的时候抛出NoSuchElementException。* poll()稍有差异,它在列表为空的时候返回null。*/System.out.println("pets.remove():" + pets.remove());System.out.println("pets.removeFirst():" + pets.removeFirst());System.out.println("pets.poll():" + pets.poll());/*** addFirst()将某个元素插入到列表的首端* offer()、add()和addLast()相同,它们都将某个元素插入到列表的尾端*/System.out.println(pets);pets.addFirst(new Pet("Hamster"));System.out.println("After addFirst():" + pets);pets.offer(new Pet("Cymric"));System.out.println("After offer():" + pets);pets.add(new Pet("Huangfei"));System.out.println("After add():" + pets);pets.addLast(new Pet("Xiaoli"));System.out.println("After addLast():" + pets);//removeLast()移除并返回列表的最后一个元素System.out.println("pets.removeLast():" + pets.removeLast());}}
//output
[Rat, Manx, Mutt, Pug]
pets.getFirst():Rat
pets.element():Rat
pets.peek():Rat
pets.remove():Rat
pets.removeFirst():Manx
pets.poll():Mutt
[Pug]
After addFirst():[Hamster, Pug]
After offer():[Hamster, Pug, Cymric]
After add():[Hamster, Pug, Cymric, Huangfei]
After addLast():[Hamster, Pug, Cymric, Huangfei, Xiaoli]
pets.removeLast():Xiaoli

创建一个空的LinkedList,通过使用ListIterator,将若干个Integer插入这个List,插入时,总是将它们插入到List的中间。

package com.huangfei.thinkinginjava.holding;import java.util.LinkedList;
import java.util.ListIterator;public class MiddleInsertion {public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<Integer>();ListIterator<Integer> lt = list.listIterator();for (int i = 1; i <= 10; i++) {lt.add(i);if(i % 2 == 0)lt.previous();}System.out.println(list);}}
//output
[1, 3, 5, 7, 9, 10, 8, 6, 4, 2]

Stack

尽管已经有了java.util.Stack,但是由于Java设计者在创建时使用了继承的方式(继承List),使得java.util.Stack具有其他不需要的方法,所以通过LinkedList实现自定义Stack会是一种比较好的选择。

package com.huangfei.thinkinginjava.holding;import java.util.LinkedList;
/*** 用LinkedList实现栈* @author huangfei** @param <T>*/
public class Stack<T> {private LinkedList<T> storage = new LinkedList<T>();public void push(T t){storage.addFirst(t);}public T peek(){return storage.peek();}public T pop(){return storage.removeFirst();}public boolean isEmpty(){return storage.isEmpty();}public String toString(){return storage.toString();}}

Queue

LinkedList提供了方法以支持队列的行为,并且它实现了Queue接口,因此LinkedList可以用作Queue的一种实现。

PriorityQueue是所谓的优先级队列,比如构建了一个消息系统,某些消息比其他消息更重要,因而应该更快地得到处理,那么它们何时得到处理就与它们何时到达无关。

当在PriorityQueue调用offer()方法来插入一个对象时,这个对象会在队列中被排序,默认的排序将使用对象在队列中的自然顺序,但是可以通过提供Comparator来修改这个顺序。

package com.huangfei.thinkinginjava.holding;import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;public class PriorityQueueDemo {private static void printQueue(Queue queue){while(queue.peek() != null)System.out.print(queue.remove() + " ");System.out.println();}public static void main(String[] args) {PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>();Random rand = new Random(47);for (int i = 0; i < 10; i++) {priorityQueue.offer(rand.nextInt(i + 10));}/*** 在PriorityQueue中,重复是允许的,最小的值拥有最高的优先级(如果是String,空格也可以算作值,并且比字母的优先级高)。*/printQueue(priorityQueue);List<Integer> ints = Arrays.asList(25, 22, 20, 18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25);priorityQueue = new PriorityQueue<Integer>(ints);printQueue(priorityQueue);/*** 通过传入Collections.reverseOrder()使得PriorityQueue产生反序的效果*/priorityQueue = new PriorityQueue<Integer>(ints.size(), Collections.reverseOrder());priorityQueue.addAll(ints);printQueue(priorityQueue);PriorityQueue<Dummy> queue = new PriorityQueue<Dummy>();System.out.println("Adding 1st instance...");queue.offer(new Dummy());System.out.println("Adding 2nd instance...");/***  会报java.lang.ClassCastException: com.huangfei.thinkinginjava.holding.Dummy *                                      cannot be cast to java.lang.Comparable*  Integer、String已经内建了自然排序,如果想在PriorityQueue中使用自己的类,就必须包含额外的功能以产生自然排序,*  或者必须提供自己的Comparator。*/queue.offer(new Dummy());}}class Dummy {
}//output
0 1 1 1 1 1 3 5 8 14 
1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25 
25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1 
Adding 1st instance...
Adding 2nd instance...
Exception in thread "main" java.lang.ClassCastException: com.huangfei.thinkinginjava.holding.Dummy cannot be cast to java.lang.Comparableat java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633)at java.util.PriorityQueue.siftUp(PriorityQueue.java:629)at java.util.PriorityQueue.offer(PriorityQueue.java:329)at com.huangfei.thinkinginjava.holding.PriorityQueueDemo.main(PriorityQueueDemo.java:52)

这篇关于持有对象(集合)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/943051

相关文章

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

Java实现将byte[]转换为File对象

《Java实现将byte[]转换为File对象》这篇文章将通过一个简单的例子为大家演示Java如何实现byte[]转换为File对象,并将其上传到外部服务器,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言1. 问题背景2. 环境准备3. 实现步骤3.1 从 URL 获取图片字节数据3.2 将字节数组

Javascript访问Promise对象返回值的操作方法

《Javascript访问Promise对象返回值的操作方法》这篇文章介绍了如何在JavaScript中使用Promise对象来处理异步操作,通过使用fetch()方法和Promise对象,我们可以从... 目录在Javascript中,什么是Promise1- then() 链式操作2- 在之后的代码中使

MyBatis的配置对象Configuration作用及说明

《MyBatis的配置对象Configuration作用及说明》MyBatis的Configuration对象是MyBatis的核心配置对象,它包含了MyBatis运行时所需的几乎所有配置信息,这个对... 目录MyBATis配置对象Configuration作用Configuration 对象的主要作用C

SpringBoot实现导出复杂对象到Excel文件

《SpringBoot实现导出复杂对象到Excel文件》这篇文章主要为大家详细介绍了如何使用Hutool和EasyExcel两种方式来实现在SpringBoot项目中导出复杂对象到Excel文件,需要... 在Spring Boot项目中导出复杂对象到Excel文件,可以利用Hutool或EasyExcel

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元