英文:
Can we remove element from a queue using given index position?
问题
public static void deleteFromQueue(PassengerQueue passengerQueue){
//passengerQueue.dequeue();
Scanner scan = new Scanner(System.in);
System.out.print("请输入乘客姓名:");
String name = scan.nextLine();
for (int i=0; i<passengerQueue.getPassenger().length; i++){
if (passengerQueue.getPassenger()[i].getName().equals(name)){
//
}
}
}
这是我的移除方法
<details>
<summary>英文:</summary>
I implemented a queue using array. Now I want to remove a element by searching, if the element were there it must be removed from the queue.
```java
public static void deleteFromQueue(PassengerQueue passengerQueue){
//passengerQueue.dequeue();
Scanner scan = new Scanner(System.in);
System.out.print("please Enter the Passenger name: ");
String name = scan.nextLine();
for (int i=0; i<passengerQueue.getPassenger().length; i++){
if (passengerQueue.getPassenger()[i].getName().equals(name)){
//
}
}
}
here my method of removing
答案1
得分: 1
为什么您特别想要使用一个 array
。以下附有使用 ArrayList
的示例:
package stackoverflow;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Iterator;
public class QuickTest {
@Test
public void test() throws Exception {
PassengerQueue passengerQueue = new PassengerQueue();
passengerQueue.add(new Passenger("testName1"));
passengerQueue.add(new Passenger("testName2"));
Assertions.assertEquals(2, passengerQueue.size());
PassengerUtil.removeByName(passengerQueue, "testName1");
Assertions.assertEquals(passengerQueue.size(), 1);
System.out.println("All done");
}
private static class PassengerUtil {
/** @param passengerQueue Modified by reference. **/
private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
// Using an Iterator so that I don't trigger ConcurrentModificationException.
for (Iterator<Passenger> it = passengerQueue.iterator() ; it.hasNext() ; ) {
Passenger currPassenger = it.next();
if (currPassenger.getName().equals(specifiedName)) {
it.remove();
}
}
}
}
private class PassengerQueue extends ArrayList<Passenger> {
}
private class Passenger {
private String name;
public Passenger(String name) {
if (name == null) {
throw new NullPointerException("The " + Passenger.class.getSimpleName() + " cannot have a Name equal to NULL!");
}
this.name = name;
}
public String getName() {
return this.name;
}
}
}
请注意以下内容:
-
我的
PassengerQueue
对象扩展了ArrayList
。因此,通过扩展ArrayList
,我就有了一个类型安全的Passenger
列表 - 我不需要做其他任何事情。 -
我使用 Iterator 来遍历列表。它比普通的 for-each 循环 稍微冗长,但是它是不触发 ConcurrentModificationException 的必要条件。在遍历列表的同时从列表中删除元素时,Java 并不总是喜欢这样做。(也许简单的示例不会触发
ConcurrentModificationException
) -
您将列表称为
PassengerQueue
。请注意,Java 确实有Queue
(https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html)集合。类似于我扩展ArrayList
,您可以查看Queue
的子类,并在需要使您的 Collection 函数像队列一样时扩展它。 -
您的代码和我的代码目前都可以从列表中删除具有相同名称的
Passenger
。 -
您的问题标题问如何通过索引位置从
array
中删除。您可以考虑将 Apache Commons Lang 项目添加到类路径中,并使用其中的方法,如 ArrayUtils
实际上,我的答案可以进一步改进,甚至不需要使用 Iterator
:
private static class PassengerUtil {
/** @param passengerQueue Modified by reference. **/
private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
passengerQueue.removeIf(currPassenger -> currPassenger.getName().equals(specifiedName));
}
}
有关后一个代码示例的更多信息,请查看 此处。
英文:
Why do you specifically want to use an array
. Please find an example attached using an ArrayList
:
package stackoverflow;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Iterator;
public class QuickTest {
@Test
public void test() throws Exception {
PassengerQueue passengerQueue = new PassengerQueue();
passengerQueue.add(new Passenger("testName1"));
passengerQueue.add(new Passenger("testName2"));
Assertions.assertEquals(2, passengerQueue.size());
PassengerUtil.removeByName(passengerQueue, "testName1");
Assertions.assertEquals(passengerQueue.size(), 1);
System.out.println("All done");
}
private static class PassengerUtil {
/** @param passengerQueue Modified by reference. **/
private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
// Using an Iterator so that I don't trigger ConcurrentModificationException.
for (Iterator<Passenger> it = passengerQueue.iterator() ; it.hasNext() ; ) {
Passenger currPassenger = it.next();
if (currPassenger.getName().equals(specifiedName)) {
it.remove();
}
}
}
}
private class PassengerQueue extends ArrayList<Passenger> {
}
private class Passenger {
private String name;
public Passenger(String name) {
if (name == null) {
throw new NullPointerException("The " + Passenger.class.getSimpleName() + " cannot have a Name equal to NULL!");
}
this.name = name;
}
public String getName() {
return this.name;
}
}
}
Please note the following:
-
My
PassengerQueue
object extendsArrayList
. So I have a type-safe list ofPassenger
s just by extendingArrayList
- I don't need to do anything else. -
I use an Iterator to iterate over the list. Its a bit more verbose than your normal for-each loop, but its necessary to not trigger a ConcurrentModificationException. Java doesn't always like when you iterate over a list and then for example delete things from that list while you're iterating over it. (Maybe simple examples won't trigger the
ConcurrentModificationException
) -
You called your list
PassengerQueue
. Please note that Java does haveQueue
(https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) collections. Similar to me extendingArrayList
you can look atQueue
subclasses and extend that instead if you really need your Collection to function like a queue. -
Your code, and mine, can currently delete multiple elements from the list if the list contains
Passenger
s with the same name. -
Your question title asked about deleting from an
array
using an index position. You can consider adding the Apache Commons Lang project to your classpath and using methods from their ArrayUtils
Actually, my answer can be improved to not even use an Iterator
:
private static class PassengerUtil {
/** @param passengerQueue Modified by reference. **/
private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
passengerQueue.removeIf(currPassenger -> currPassenger.getName().equals(specifiedName));
}
}
Some reading on the latter code example here.
答案2
得分: 1
一个'Queue'被定义为一种数据结构,它保存一个项目序列,您只能将某些东西添加到末尾('尾部'),并且可以从开头('头部')取出某些东西。有时会说您可以获取序列的当前大小,询问序列是否为空,并且您可以查看('peek')第一个项目而不将其取出。
那就是基础。而且您可以用不同的方式实现它。
在Java中有一个接口(java.util.Queue
),提供了上述基本功能。所以当您声明
java.util.Queue myQueue = …
然后您不能搜索队列中的项目并将其删除(好吧,您可以逐个从队列中取出所有元素,然后再添加要保留的元素,但这很繁琐)。
但是java.util.Queue
的实现是java.util.LinkedList
,而列表是可以搜索的。
所以您写了
java.util.Queue myQueue = new java.util.LinkedList();
并且由于您现在知道您的队列的实现实际上是一个列表,您可以写成
…
for (var i = ((java.util.List) myQueue).iterator(); i.hasNext(); ) {
if (matchesCriteriaForRemoval(i.next())) i.remove();
}
…
但这只能工作是因为您知道myQueue
的一些实现细节 - 但这正是您在选择将其定义为java.util.Queue
时想要隐藏的内容。
因此,当您必须能够从您的PassengerQueue
中删除条目时,该数据结构应该提供一种方法来实现此操作,而不是揭示其内部实现。
这意味着您的代码应该如下所示:
public static void deleteFromQueue(PassengerQueue passengerQueue) {
Scanner scan = new Scanner(System.in);
System.out.print("请输入乘客姓名:");
String name = scan.nextLine();
passengerQueue.removeByName(name);
}
方法PassengerQueue.removeByName()
的实现方式取决于PassengerQueue
的内部实现;如果它使用名为passengers
的java.util.List
来存储乘客,它可能如下所示:
public final void removeByName(final String name) {
for (var i = passengers.iterator(); i.hasNext(); ) {
if (passengerNameMatches(name, i.next())) i.remove();
}
}
如果您为乘客使用另一个容器,那么该删除方法必须以不同的方式实现…
显然,我省略了所有错误处理,集合是泛型类型,但由于简洁起见,我将它们用作原始类型。
英文:
A 'Queue' is defined as a data structure that holds a sequence of items where you can only add something to the end (the 'tail') and where you can take something from the beginning, the 'head'. And sometimes it is said that you can get the current size of the sequence, ask whether the sequence is empty, and that you can look ('peek') at the first item without taking it.
That's the basics. And you can implement that in various ways.
There is an interface in Java (java.util.Queue
) that provides the basic features described above. So when you declare
java.util.Queue myQueue = …
then you cannot search your queue for an item and remove it (ok, you can take all elements from your queue, one by one, and add again those you want to keep, but that's tedious).
But the implementation for java.util.Queue
is java.util.LinkedList
, and a list can be searched.
So you write
java.util.Queue myQueue = new java.util.LinkedList();
and as you now know that the implementation of your queue is in fact a list, you can write
…
for( var i = ((java.util.List) myQueue).iterator(); i.hasNext(); )
{
if( matchesCriteriaForRemoval( i.next() ) i.remove();
}
…
But this works only because you know some implementation details of myQueue
– but that was what you want to hide when you chose to define it as java.util.Queue
.
So when you have to be able to remove entries from your PassengerQueue
, that data structure should provide a method to do so instead of revealing its internal implementation.
This means your code have to look like this:
public static void deleteFromQueue( PassengerQueue passengerQueue )
{
Scanner scan = new Scanner( System.in );
System.out.print( "please Enter the Passenger name: " );
String name = scan.nextLine();
passengerQueue.removeByName( name );
}
How this method PassengerQueue.removeByName()
is implemented depends from the internal implementation of PassengerQueue
; if it uses the java.util.List
with the name passengers
to store the passengers, it may look like this:
public final void removeByName( final String name )
{
for( var i = passengers.iterator(); i.hasNext(); )
{
if( passengerNameMatches( name, i.next() ) ) i.remove();
}
}
If you use another container for your passengers, that removal method has to be implemented differently …
Obviously I omitted all error handling, and the collections are generic types, but I used them as raw because of brevity.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论