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.
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
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 extends ArrayList. So I have a type-safe list of Passengers just by extending ArrayList - 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 have Queue(https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) collections. Similar to me extending ArrayList you can look at Queue 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 Passengers 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.
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.
Related
I used TreeSet for this and it works in a per snapshot style. In other words, sort once displays once.
Now, I want to implement a realtime sorted table.
Whenever there is a value change in any elements, the sorted table will be updated accordingly.
To make the sorting work on a per update style, I tried to remove the element and add it to the TreeSet again.
quotes.remove(quote);
quotes.add(quote);
It doesn't work because I have to implement the sorting logic in compareTo() but it breaks the contract for identifying the object which makes the remove() work. TreeSet never call equals() and hashcode() as described in the Java Doc.
Any idea? Please advise.
code:
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String args[]) {
TreeSetTest test = new TreeSetTest();
test.onQuoteUpdate("appl", 1000d);
test.onQuoteUpdate("msft", 2000d);
test.onQuoteUpdate("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("msft", 5000d);
test.printTopStocks();
}
private Set<Quote> quotes = new TreeSet<Quote>();
public void onQuoteUpdate(String symbol, double turnover) {
final Quote quote = new Quote(symbol, turnover);
quotes.remove(quote);
quotes.add(quote);
}
public void printTopStocks() {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}
public static class Quote implements Comparable<Quote> {
private String symbol;
private double turnover;
public Quote(String symbol, double turnover) {
this.symbol = symbol;
this.turnover = turnover;
}
#Override
public int compareTo(Quote o) {
return Double.compare(o.turnover, turnover);
// return symbol.compareTo(o.symbol);
}
}
}
Update 1:
As proposed I tried this:
public static void main(String args[]) {
TreeMapTest test = new TreeMapTest();
test.onQuoteUpdate("appl", 1000d);
test.onQuoteUpdate("msft", 2000d);
test.onQuoteUpdate("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("face", 50d);
test.printTopStocks();
}
public int compareTo(Quote o) {
if(o.symbol.equals(symbol)) return 0;
return Double.compare(o.turnover, turnover);
}
The remove() return false which eventually there are four elements (expected 3) in the Set.
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
remove symbol face : false
add symbol face : true
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
Quote [symbol=face, turnover=50.0]
Update 2:
I tried PriorityQueue and here is the code:
https://code.sololearn.com/cb38Eo036c8y/#java
It doesn't work because PriorityQueue doesn't store elements in order. The ordering only works when you poll element from the Queue.
Update 3:
Tried user54321's suggestion that by using a custom collection(see below answer). However, it doesn't look good if there are two more elements having the same value of 'turnover'.
My requirement is a very ordinary one. It seems that none of a collection from JDK fits my case.
Update 4:
The solution from user54321 fits for my interim need.
https://code.sololearn.com/c14Ybab7AOFm/#java
Deleted my previously added answer. Looks like a wrong data structure is being used for the scenario.
Here is why.
When an item is being added or removed, TreeSet does a binary search through the available elements using compareTo().
In your case,
After adding first 3 elements, set looks like this.
[{appl, 1000d}, {msft, 2000d}, {face, 3000d}]
Now when you try to remove the element {face, 50d},
It starts searching at {msft, 2000d},
From compareTo() result it determines {face, 50d} should come before {msft, 2000d}.
And continues to search towards start of the elements ( checking with {appl, 1000d} next).
Since the search doesn't find {face, 3000d}, that element remains without being removed.
Next when you add the element {face,50}, similar search happens and since the search does not find {face, 3000},
It adds {face, 50} to the beginning.
Now the set looks like this.
[{face, 50}, {appl, 1000d}, {msft, 2000d}, {face, 3000d}]
Now the problem here is that compareTo() isn't capable of considering both symbol and turnover for a sensible sorting.
TreeSet can be used for getting a sorted collection of unique elements.
If you need to get a sorted collection of different objects with a particular sorting criteria, in this case turnover value, you can use a PriorityQueue
Update: Using a List and a Set in custom data structure
The problem here is that we have to maintain two conditions.
1. Symbol has to be unique
2. Collection should be sorted by turnover value
compareTo() in Quote can check one at a time and not both.
So in this case we may have to go for a custom data structure.
First use only turnover in compareTo();
#Override
public int compareTo(Quote o) {
return Double.compare(o.turnover, turnover);
}
Then implement the custom data structure.
Note that we are using a HashSet to keep track of the symbol alone.
Using a list so that duplicate turnover values can be kept.
static class QuoteCollection {
Set<String> symbols = new HashSet<>();
List<Quote> quotes = new LinkedList<>();
public void onQuoteUpdate(Quote q) {
if (symbols.contains(q.getSymbol())) {
// this requires quotes.equals() to be implemented
quotes.remove(q);
} else {
symbols.add(q.getSymbol());
}
insertToCollection(q);
}
// inserting at correct position to remain sorted
private void insertToCollection(Quote q) {
int index = Collections.binarySearch(quotes, q);
if (index < 0)
index = ~index; // bitwise compliment to find insert position if it is not available in the list
quotes.add(index, q);
}
public List<Quote> getQuotes() {
return quotes;
}
}
Then use it in the main(). Note that printTopStocks() has been changed a little.
public static void main(String args[]) {
Main test = new Main();
QuoteCollection quoteCollection = new QuoteCollection();
quoteCollection.onQuoteUpdate(new Quote("appl", 1000d));
quoteCollection.onQuoteUpdate(new Quote("msft", 2000d));
quoteCollection.onQuoteUpdate(new Quote("face", 3000d));
test.printTopStocks(quoteCollection.getQuotes());
quoteCollection.onQuoteUpdate(new Quote("face", 50d));
test.printTopStocks(quoteCollection.getQuotes());
}
public void printTopStocks(List<Quote> quotes) {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}
This approach does involve data duplication. However a sorted collection can be maintained at linear time complexity(since it uses 'List.remove()')
Couple of points :
Trying to remove elements even when you are adding it first time.
While updating you are trying to remove new element which does not exist in TreeSet. final Quote quote = new Quote(symbol, turnover); here you are building new element which is Quote("face","50d") which does not exist when you are calling quotes.remove(quote);
Below is the one of the way to solve it, I am hard coding oldQuote to keep it short but you can update it:
public void onAdd(String symbol, double turnover) {
final Quote quote = new Quote(symbol, turnover);
quotes.remove(quote);
quotes.add(quote);
}
public void onQuoteUpdate(String symbol, double turnover) {
final Quote newQuote = new Quote(symbol, turnover);
final Quote oldQuote = new Quote("face", 3000d);
quotes.remove(oldQuote);
quotes.add(quote);
}
public static void main(String args[]) {
TreeSetTest test = new TreeSetTest();
test.onAdd("appl", 1000d);
test.onAdd("msft", 2000d);
test.onAdd("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("face", 50d);
test.printTopStocks();
}
So I'm making a search algorithm. I'm using a queue to store all of my objects
This is how I initialised it
Queue<Node> queue = new LinkedList<Node>();
I want to compare a variable in each object and order to queue. My plan is to use a for loop to compare the first object with each of the other objects and whichever object has the lowest variable is sent to the front of the queue. Then move onto the next object and repeat the process. My issue is I'm not sure how to retrieve an object from the queue that isn't the first object in the queue....
You could do a for loop through the Queue:
for (Node n : queue) {
do stuff with n
}
However, you aren't going to be able to remove items from the middle of the queue. Might I suggest a structure like an ArrayList?
In my opinion the best way is to use PriorityQueue. You can specify implementation of Comparator interface that will impose how elements should be sorted inside of queue.
Here is an example:
Let's say that this is your Node class:
public class Node {
// this field will be used to sort in queue
private int value;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return "My value is: " + value;
}
}
And here is example of adding Nodes into queue:
import java.util.PriorityQueue;
import java.util.Random;
public class QueueExample {
public static void main(String[] args) {
Random r = new Random();
// Priority queue with custom comparator
PriorityQueue<Node> queue = new PriorityQueue<Node>(10, new SampleNodeComparator());
// adding 100 nodes with random value
for(int i = 0; i < 100; ++i) {
queue.add( new Node(r.nextInt(1000)));
}
// nodes will be removed from queue in order given by comparator
while(queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
And the most important part - implementation of our custom comparator
import java.util.Comparator;
// our comparator needs to implements Comparator interface
public class SampleNodeComparator implements Comparator<Node> {
#Override
public int compare(Node o1, Node o2) {
/*
value that should be return from compare method should follow rules:
if o1 == o2 - return 0
if o1 > o2 - return any positive value
if o1 < 02 - return any negative value
*/
return o1.getValue() - o2.getValue();
}
}
When you run main method from QueueExample class you will see on console that values are removed from queue sorted by Node.value value.
Use Queue<E>#peek () to retrieve an object without removing it.
Some example code:
import java.util.*;
class Example {
public static void main (String[] args) throws Exception {
Queue<String> list = new PriorityQueue<>();
{ // Initialize the Queue
list.add ("Hello ");
list.add ("Mrs. ");
list.add ("DoubtFire! ");
}
System.out.println (list);
// Iterating through the Queue
String element;
while ( (element = list.peek()) != null) {
if (element.equals ("Mrs. ")) {
System.out.println ("\"Mrs\" found!");
}
System.out.println (element);
list.remove (element);
}
System.out.println (list); // Empty by now...
}
}
Output:
[DoubtFire! , Mrs. , Hello ]
DoubtFire!
Hello
"Mrs" found!
Mrs.
[]
Queue interface does not guarantee any particular order while iterating or polling so theoretically this task is impossible to implement with Queue.
Seeing your response to my comment, I think that in your case, you should use the PriorityQueue because it does what you need without needing you to reinvent the wheel, which is usually not recommended.
By default, the priority queue will use the default implementation of the compareTo method. Assuming that you have a composite type, you have two options:
You can make your custom class implement the Comparabale interface and have your sorting logic there.
Alternatively, you could pass your own comparator:
PriorityQueue<..> p = new PriorityQueue<..>(5, new Comparator<..>()
{
#override
public int compare(.. type1, .. type2)
{
//comparison logic done here.
}
}
You can take a look at this short tutorial for more information.
I have Arraylist of objects ArrayList<Product> productDatabase. The object contains a String and a double and then these objects will be added to the productDatabase by addProductToDatabase(); as follows:
public void addProductToDatabase(String productName, double dimensions); {
Product newProduct = new Product(ProductName, dimensions);
productDatabase.add(newProduct);
}
I also want to make an Arraylist<ProductCount> productInventory which counts how many Product are accounted for. Before it can add to ArrayList<ProductCount> productInventory however, it should first check if the object details exist in the productDatabase while running addProductToInventory()
public Product getProduct(String name) {
for(i = 0; i < productDatabase.size(); i++)
if(productDatabase.get(i).contains(name) //Error: cannot find symbol- method contains.(java.lang.String)
return productDatabase.get(i)
}
public void addProductToInventory(String productName, double quantity)
{
Product p = getProduct(name);
productCount.add(new ProductCount(o, quantity));
}
Assume that you always have different objects (so nothing will have the same name), but you're always unsure of the dimensions (so when you input the same producttName + dimensions you edit the dimensions in it).
At the end of the day, you have to put all the items in it a large box and report what you've inventoried, so you also have a getProductQuantityTotal() and you have to getProductDimensionTotal()-- as the name suggests, get the total of number of objects you've counted, and the sum of the dimensions.
What do I have to add/change/remove about this code? Don't consider syntax first (because BlueJ checks for common syntax errors and I just typed this by hand). I'm sure that I'm missing a for statement somewhere, and I'm probably misusing contains() because it won't recognise it (I have import java.util.*; and import java.util.ArrayList;)
To answer the question in your post title: How to find a string in an object, for a list of those objects, here is some sample code that does this:
First, I created a trivial object that has a string field:
class ObjectWithStringField {
private final String s;
public ObjectWithStringField(String s) {
this.s = s;
}
public String getString() {
return s;
}
}
And then a code that populates a list of it, and then searches each for the string. There's no magic here, it just iterates through the list until a match is found.
import java.util.List;
import java.util.Arrays;
/**
<P>{#code java StringInObjectInList}</P>
**/
public class StringInObjectInList {
public static final void main(String[] ignored) {
ObjectWithStringField[] owStrArr = new ObjectWithStringField[] {
new ObjectWithStringField("abc"),
new ObjectWithStringField("def"),
new ObjectWithStringField("ghi")};
//Yes this is a List instead of an ArrayList, but you can easily
//change this to work with an ArrayList. I'll leave that to you :)
List<ObjectWithStringField> objWStrList = Arrays.asList(owStrArr);
System.out.println("abc? " + doesStringInObjExistInList("abc", objWStrList));
System.out.println("abcd? " + doesStringInObjExistInList("abcd", objWStrList));
}
private static final boolean doesStringInObjExistInList(String str_toFind, List<ObjectWithStringField> owStrList_toSearch) {
for(ObjectWithStringField owStr : owStrList_toSearch) {
if(owStr.getString().equals(str_toFind)) {
return true;
}
}
return false;
}
}
Output:
[C:\java_code\]java StringInObjectInList
abc? true
abcd? false
In the real world, instead of a List, I'd use a Map<String,ObjectWithStringField>, where the key is that field. Then it'd be as simple as themap.containsKey("abc");. But here it is implemented as you require. You'll still have quite a bit of work to do, to get this working as specifically required by your assignment, but it should get you off to a good start. Good luck!
I am trying to print out all the elements of a List, however it is printing the pointer of the Object rather than the value.
This is my printing code...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
Could anyone please help me why it isn't printing the value of the elements.
The following is compact and avoids the loop in your example code (and gives you nice commas):
System.out.println(Arrays.toString(list.toArray()));
However, as others have pointed out, if you don't have sensible toString() methods implemented for the objects inside the list, you will get the object pointers (hash codes, in fact) you're observing. This is true whether they're in a list or not.
Since Java 8, List inherits a default "forEach" method which you can combine with the method reference "System.out::println" like this:
list.forEach(System.out::println);
Here is some example about getting print out the list component:
public class ListExample {
public static void main(String[] args) {
List<Model> models = new ArrayList<>();
// TODO: First create your model and add to models ArrayList, to prevent NullPointerException for trying this example
// Print the name from the list....
for(Model model : models) {
System.out.println(model.getName());
}
// Or like this...
for(int i = 0; i < models.size(); i++) {
System.out.println(models.get(i).getName());
}
}
}
class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
System.out.println(list);//toString() is easy and good enough for debugging.
toString() of AbstractCollection will be clean and easy enough to do that. AbstractList is a subclass of AbstractCollection, so no need to for loop and no toArray() needed.
Returns a string representation of this collection. The string representation consists of a list of the collection's elements in the
order they are returned by its iterator, enclosed in square brackets
("[]"). Adjacent elements are separated by the characters ", " (comma
and space). Elements are converted to strings as by
String.valueOf(Object).
If you are using any custom object in your list, say Student , you need to override its toString() method(it is always good to override this method) to have a meaningful output
See the below example:
public class TestPrintElements {
public static void main(String[] args) {
//Element is String, Integer,or other primitive type
List<String> sList = new ArrayList<String>();
sList.add("string1");
sList.add("string2");
System.out.println(sList);
//Element is custom type
Student st1=new Student(15,"Tom");
Student st2=new Student(16,"Kate");
List<Student> stList=new ArrayList<Student>();
stList.add(st1);
stList.add(st2);
System.out.println(stList);
}
}
public class Student{
private int age;
private String name;
public Student(int age, String name){
this.age=age;
this.name=name;
}
#Override
public String toString(){
return "student "+name+", age:" +age;
}
}
output:
[string1, string2]
[student Tom age:15, student Kate age:16]
Use String.join()
for example:
System.out.print(String.join("\n", list));
The Java 8 Streams approach...
list.stream().forEach(System.out::println);
The objects in the list must have toString implemented for them to print something meaningful to screen.
Here's a quick test to see the differences:
public class Test {
public class T1 {
public Integer x;
}
public class T2 {
public Integer x;
#Override
public String toString() {
return x.toString();
}
}
public void run() {
T1 t1 = new T1();
t1.x = 5;
System.out.println(t1);
T2 t2 = new T2();
t2.x = 5;
System.out.println(t2);
}
public static void main(String[] args) {
new Test().run();
}
}
And when this executes, the results printed to screen are:
t1 = Test$T1#19821f
t2 = 5
Since T1 does not override the toString method, its instance t1 prints out as something that isn't very useful. On the other hand, T2 overrides toString, so we control what it prints when it is used in I/O, and we see something a little better on screen.
Or you could simply use the Apache Commons utilities:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ArrayUtils.html#toString-java.lang.Object-
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
Consider a List<String> stringList which can be printed in many ways using Java 8 constructs:
stringList.forEach(System.out::println); // 1) Iterable.forEach
stringList.stream().forEach(System.out::println); // 2) Stream.forEach (order maintained generally but doc does not guarantee)
stringList.stream().forEachOrdered(System.out::println); // 3) Stream.forEachOrdered (order maintained always)
stringList.parallelStream().forEach(System.out::println); // 4) Parallel version of Stream.forEach (order not maintained)
stringList.parallelStream().forEachOrdered(System.out::println); // 5) Parallel version ofStream.forEachOrdered (order maintained always)
How are these approaches different from each other?
First Approach (Iterable.forEach)-
The iterator of the collection is generally used and that is designed to be fail-fast which means it will throw ConcurrentModificationException if the underlying collection is structurally modified during the iteration. As mentioned in the doc for ArrayList:
A structural modification is any operation that adds or deletes one or
more elements, or explicitly resizes the backing array; merely setting
the value of an element is not a structural modification.
So it means for ArrayList.forEach setting the value is allowed without any issue. And in case of concurrent collection e.g. ConcurrentLinkedQueue the iterator would be weakly-consistent which means the actions passed in forEach are allowed to make even structural changes without ConcurrentModificationExceptionexception being thrown. But here the modifications might or might not be visible in that iteration.
Second Approach (Stream.forEach)-
The order is undefined. Though it may not occur for sequential streams but the specification does not guarantee it. Also the action is required to be non-interfering in nature. As mentioned in doc:
The behavior of this operation is explicitly nondeterministic. For
parallel stream pipelines, this operation does not guarantee to
respect the encounter order of the stream, as doing so would sacrifice
the benefit of parallelism.
Third Approach (Stream.forEachOrdered)-
The action would be performed in the encounter order of the stream. So whenever order matters use forEachOrdered without a second thought. As mentioned in the doc:
Performs an action for each element of this stream, in the encounter
order of the stream if the stream has a defined encounter order.
While iterating over a synchronized collection the first approach would take the collection's lock once and would hold it across all the calls to action method, but in case of streams they use collection's spliterator, which does not lock and relies on the already established rules of non-interference. In case collection backing the stream is modified during iteration a ConcurrentModificationException would be thrown or inconsistent result may occur.
Fourth Approach (Parallel Stream.forEach)-
As already mentioned no guarantee to respect the encounter order as expected in case of parallel streams. It is possible that action is performed in different thread for different elements which can never be the case with forEachOrdered.
Fifth Approach (Parallel Stream.forEachOrdered)-
The forEachOrdered will process the elements in the order specified by the source irrespective of the fact whether stream is sequential or parallel. So it makes no sense to use this with parallel streams.
I have faced similar problems. My code:
List<Integer> leaveDatesList = new ArrayList<>();
.....inserted value in list.......
Way 1: printing a list in a for loop
for(int i=0;i<leaveDatesList.size();i++){
System.out.println(leaveDatesList.get(i));
}
Way 2: printing the list in a forEach, for loop
for(Integer leave : leaveDatesList){
System.out.println(leave);
}
Way 3: printing the list in java 8
leaveDatesList.forEach(System.out::println);
You haven't specified what kind of elements the list contains, if it is a primitive data type then you can print out the elements.
But if the elements are objects then as Kshitij Mehta mentioned you need to implement (override) the method "toString" within that object - if it is not already implemented - and let it return something meaning full from within the object, example:
class Person {
private String firstName;
private String lastName;
#Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
It depends on what type of objects stored in the List, and whether it has implementation for toString() method. System.out.println(list) should print all the standard java object types (String, Long, Integer etc). In case, if we are using custom object types, then we need to override toString() method of our custom object.
Example:
class Employee {
private String name;
private long id;
#Override
public String toString() {
return "name: " + this.name() +
", id: " + this.id();
}
}
Test:
class TestPrintList {
public static void main(String[] args) {
Employee employee1 =new Employee("test1", 123);
Employee employee2 =new Employee("test2", 453);
List<Employee> employees = new ArrayList(2);
employee.add(employee1);
employee.add(employee2);
System.out.println(employees);
}
}
For a list of array of String
list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
For loop to print the content of a list :
List<String> myList = new ArrayList<String>();
myList.add("AA");
myList.add("BB");
for ( String elem : myList ) {
System.out.println("Element : "+elem);
}
Result :
Element : AA
Element : BB
If you want to print in a single line (just for information) :
String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
Result :
Elements : AA, BB
System.out.println(list); works for me.
Here is a full example:
import java.util.List;
import java.util.ArrayList;
public class HelloWorld {
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
System.out.println(list);
}
}
It will print [Hello, World].
list.stream().map(x -> x.getName()).forEach(System.out::println);
I wrote a dump function, which basicly prints out the public members of an object if it has not overriden toString(). One could easily expand it to call getters.
Javadoc:
Dumps an given Object to System.out, using the following rules:
If the Object is Iterable, all of its components are dumped.
If the Object or one of its superclasses overrides toString(), the "toString" is dumped
Else the method is called recursively for all public members of the Object
/**
* Dumps an given Object to System.out, using the following rules:<br>
* <ul>
* <li> If the Object is {#link Iterable}, all of its components are dumped.</li>
* <li> If the Object or one of its superclasses overrides {#link #toString()}, the "toString" is dumped</li>
* <li> Else the method is called recursively for all public members of the Object </li>
* </ul>
* #param input
* #throws Exception
*/
public static void dump(Object input) throws Exception{
dump(input, 0);
}
private static void dump(Object input, int depth) throws Exception{
if(input==null){
System.out.print("null\n"+indent(depth));
return;
}
Class<? extends Object> clazz = input.getClass();
System.out.print(clazz.getSimpleName()+" ");
if(input instanceof Iterable<?>){
for(Object o: ((Iterable<?>)input)){
System.out.print("\n"+indent(depth+1));
dump(o, depth+1);
}
}else if(clazz.getMethod("toString").getDeclaringClass().equals(Object.class)){
Field[] fields = clazz.getFields();
if(fields.length == 0){
System.out.print(input+"\n"+indent(depth));
}
System.out.print("\n"+indent(depth+1));
for(Field field: fields){
Object o = field.get(input);
String s = "|- "+field.getName()+": ";
System.out.print(s);
dump(o, depth+1);
}
}else{
System.out.print(input+"\n"+indent(depth));
}
}
private static String indent(int depth) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<depth; i++)
sb.append(" ");
return sb.toString();
}
I happen to be working on this now...
List<Integer> a = Arrays.asList(1, 2, 3);
List<Integer> b = Arrays.asList(3, 4);
List<int[]> pairs = a.stream()
.flatMap(x -> b.stream().map(y -> new int[]{x, y}))
.collect(Collectors.toList());
Consumer<int[]> pretty = xs -> System.out.printf("\n(%d,%d)", xs[0], xs[1]);
pairs.forEach(pretty);
public static void main(String[] args) {
answer(10,60);
}
public static void answer(int m,int k){
AtomicInteger n = new AtomicInteger(m);
Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(k);
System.out.println(Arrays.toString(stream.toArray()));
}
try to override toString() method as you want that the element will be printend.
so the method to print can be this:
for(int i=0;i<list.size();i++){
System.out.println(list.get(i).toString());
}
Solusion of your problem for java 11 is:
String separator = ", ";
String toPrint = list.stream().map(o -> String.valueOf(o)).collect(Collectors.joining(separator));
System.out.println(toPrint);
You can try:
for 2D(or more)
System.out.println(Arrays.deepToString(list.toArray()));
for 1D
System.out.println(Arrays.toString(list.toArray()))
List<String> textList= messageList.stream()
.map(Message::getText)
.collect(Collectors.toList());
textList.stream().forEach(System.out::println);
public class Message {
String name;
String text;
public Message(String name, String text) {
this.name = name;
this.text = text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
}
I would like to store tuples objects in a concurent java collection and then have an efficient, blocking query method that returns the first element matching a pattern. If no such element is available, it would block until such element is present.
For instance if I have a class:
public class Pair {
public final String first;
public final String Second;
public Pair( String first, String second ) {
this.first = first;
this.second = second;
}
}
And a collection like:
public class FunkyCollection {
public void add( Pair p ) { /* ... */ }
public Pair get( Pair p ) { /* ... */ }
}
I would like to query it like:
myFunkyCollection.get( new Pair( null, "foo" ) );
which returns the first available pair with the second field equalling "foo" or blocks until such element is added. Another query example:
myFunkyCollection.get( new Pair( null, null ) );
should return the first available pair whatever its values.
Does a solution already exists ? If it is not the case, what do you suggest to implement the get( Pair p ) method ?
Clarification: The method get( Pair p) must also remove the element. The name choice was not very smart. A better name would be take( ... ).
Here's some source code. It basically the same as what cb160 said, but having the source code might help to clear up any questions you may still have. In particular the methods on the FunkyCollection must be synchronized.
As meriton pointed out, the get method performs an O(n) scan for every blocked get every time a new object is added. It also performs an O(n) operation to remove objects. This could be improved by using a data structure similar to a linked list where you can keep an iterator to the last item checked. I haven't provided source code for this optimization, but it shouldn't be too difficult to implement if you need the extra performance.
import java.util.*;
public class BlockingQueries
{
public class Pair
{
public final String first;
public final String second;
public Pair(String first, String second)
{
this.first = first;
this.second = second;
}
}
public class FunkyCollection
{
final ArrayList<Pair> pairs = new ArrayList<Pair>();
public synchronized void add( Pair p )
{
pairs.add(p);
notifyAll();
}
public synchronized Pair get( Pair p ) throws InterruptedException
{
while (true)
{
for (Iterator<Pair> i = pairs.iterator(); i.hasNext(); )
{
Pair pair = i.next();
boolean firstOk = p.first == null || p.first.equals(pair.first);
boolean secondOk = p.second == null || p.second.equals(pair.second);
if (firstOk && secondOk)
{
i.remove();
return pair;
}
}
wait();
}
}
}
class Producer implements Runnable
{
private FunkyCollection funkyCollection;
public Producer(FunkyCollection funkyCollection)
{
this.funkyCollection = funkyCollection;
}
public void run()
{
try
{
for (int i = 0; i < 10; ++i)
{
System.out.println("Adding item " + i);
funkyCollection.add(new Pair("foo" + i, "bar" + i));
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
public void go() throws InterruptedException
{
FunkyCollection funkyCollection = new FunkyCollection();
new Thread(new Producer(funkyCollection)).start();
System.out.println("Fetching bar5.");
funkyCollection.get(new Pair(null, "bar5"));
System.out.println("Fetching foo2.");
funkyCollection.get(new Pair("foo2", null));
System.out.println("Fetching foo8, bar8");
funkyCollection.get(new Pair("foo8", "bar8"));
System.out.println("Finished.");
}
public static void main(String[] args) throws InterruptedException
{
new BlockingQueries().go();
}
}
Output:
Fetching bar5.
Adding item 0
Adding item 1
Adding item 2
Adding item 3
Adding item 4
Adding item 5
Fetching foo2.
Fetching foo8, bar8
Adding item 6
Adding item 7
Adding item 8
Finished.
Adding item 9
Note that I put everything into one source file to make it easier to run.
I know of no existing container that will provide this behavior. One problem you face is the case where no existing entry matches the query. In that case, you'll have to wait for new entries to arrive, and those new entries are supposed to arrive at the tail of the sequence. Given that you're blocking, you don't want to have to examine all the entries that precede the latest addition, because you've already inspected them and determined that they don't match. Hence, you need some way to record your current position, and be able to search forward from there whenever a new entry arrives.
This waiting is a job for a Condition. As suggested in cb160's answer, you should allocate a Condition instance inside your collection, and block on it via Condition#await(). You should also expose a companion overload to your get() method to allow timed waiting:
public Pair get(Pair p) throws InterruptedException;
public Pair get(Pair p, long time, TimeUnit unit) throws InterruptedException;
Upon each call to add(), call on Condition#signalAll() to unblock the threads waiting on unsatisfied get() queries, allowing them to scan the recent additions.
You haven't mentioned how or if items are ever removed from this container. If the container only grows, that simplifies how threads can scan its contents without worrying about contention from other threads mutating the container. Each thread can begin its query with confidence as to the minimum number of entries available to inspect. However, if you allow removal of items, there are many more challenges to confront.
In your FunkyCollection add method you could call notifyAll on the collection itself every time you add an element.
In the get method, if the underlying container (Any suitable conatiner is fine) doesn't contain the value you need, wait on the FunkyCollection. When the wait is notified, check to see if the underlying container contains the result you need. If it does, return the value, otherwise, wait again.
It appears you are looking for an implementation of Tuple Spaces. The Wikipedia article about them lists a few implementations for Java, perhaps you can use one of those. Failing that, you might find an open source implementation to imitate, or relevant research papers.