Iterator to return list - java

I am trying to implement this with the help of enhanced for loop, but my question is if I use the iterator for the example below how do I make sure that my return type is picking up the corresponding value of "XYZ"?
List<Apples> a1 = new List<Apples>();
if(a1.iterator().next().equals("XYZ")
{
return a1.iterator().next().getFruits();
}

Probably you want to implement the following
List<Apples> apples = new List<Apples>();
for(Apple a : apples) {
if("xyz".equals(a.getSomethingWhatReturnsString())) return a.getFruits();
}

Why use an iterator here? a simple get() will do the trick:
if (a1.get(0).equals("XYZ")) {
return a1.get(0).getFruits();
}
Of course, if you intend to traverse all the elements in a list then you're missing a for here. And besides, your code won't work: it's a list of apples, you can't compare an apple with a string! Perhaps you meant something like this, replace getStringAttribute() with the appropriate attribute that you intend to compare with "XYZ":
for (Apple a : a1) {
if ("XYZ".equals(a.getStringAttribute())) {
return a.getFruits();
}
}

Related

Check List has only one non null element and retrieve it using Java 8

How to check whether the list has only one non-null element and if so retrieve the same using java 8 or Streams?
One of my method return list of objects which needs to check whether the returned list contains only one non null object, If so it creates a map as defined below else, needs to log an error as below.
`public void myMethod() {
List<MyClass> tst = getAll();
if(!tst.isEmpty() ) {
if( tst.size() == 1) {
if(tst.get(0)!= null) {
MyClass class1 = tst.get(0);
Map<Integer,MyClass> m =
Stream.of(class1).collect(Collectors.toMap(MyClass:: getId,
Function.identity()));
}
}
else {
LOGGER.error("Multiple object found - {} object", tst.size());
}
}`
I'm looking for a way to write in a clean and standard format as I have three If conditions
Something like that should do the trick but it's not using streams. If you really need to use streams say so and I'll give it a try with it :)
int notNullCount = 0;
Object myNotNullElement;
for (Object element : myArray){
if (notNullCount > 1){
//Throw exception or do whaterver you need to do to signal this
break;
}
if (element != null){
myNotNullElement = element;
notNullCount++;
}
}

How to remove a object inside an array list

I have searched a lot for this, and checked the posts that is provided as possible answers, and none seems to give me an answer.
I have this arraylist in which i store online users.
I can read from the user list and add to it.
Problem is, I cant seem to find out how I remove it.
I have tried
online.remove("MyUsername");
My class and initialiser is like this:
ArrayList<userOnline> online = new ArrayList<userOnline>();
class userOnline {
String userName;
String data1;
String data2;
String data3;
}
I thought it would find the object row with username and remove the row, or at least the username, but it removed nothing and does not give me any errors.
What can I do to make it work? Or what can I use as an alternative if this is not possible? A pointer to a doc explaining would be more than enough help!
Thanks!
Seemed like the solution was this, but this is not considered good practice
for (int i=0; i <online.size(); i++) {
if(online.get(i).userName.equals("username")) {
online.remove(i);
}
}
After a discussion and a lot of feedback seems like the only right way for java to handle this search and remove is,
Iterator<userOnline> it = online.iterator();
while (it.hasNext()) {
userOnline user = it.next();
if (currentLogin.equals(user.userName)) {
it.remove();
}
}
I couldn't find a dupe or a suitable doc, so here it is:
Use an Iterator:
for (Iterator<userOnline> iterator = online.iterator(); iterator.hasNext();) {
if (iterator.next().getName().equals("MyUsername")) {
iterator.remove();
}
}
Basically, you can't compare apples and pears (String and userOnline) directly. Yes you could override equals, but it should really match all the properties, not just one.
A simple solution would be to search the List, comparing each objects userName property with the value you want an either return the index or object reference, which you could use to remove it.
Alternatively, you could use an Iterator and remove it as you search...
ArrayList<userOnline> online = new ArrayList<>();
userOnline newUser = new userOnline();
newUser.userName = "MyUsername";
online.add(newUser);
System.out.println(online.size());
Iterator<userOnline> it = online.iterator();
while (it.hasNext()) {
userOnline user = it.next();
if ("MyUsername".equals(user.userName)) {
it.remove();
}
}
System.out.println(online.size());
There's probably also a really cool "streams" based solution, but small steps ;)
You could create a function that takes in your list of users and finds the first occurence of a given name and removes it when it finds a user with the name given like so
public Array<userOnline> removeUserByName(Array<userOnline> users, String nameToFind)
{
for(int i = 0; i < users.size(); i++)
{
if(users.get(i).userName.equals(nameToFind))
{
users.remove(i);
return users;
}
}
return users;
}
You could also make this function part of the class you store your list of userOnline objects then you wouldn't have to pass the array into the function.
You must search through the userOnline objects contained within your ArrayList and either find the index of the match or a reference to the match. Once you have either of these, you can remove the object from the list using one of the overloaded remove() methods. Remember that by default, the equals method compares references.
The search can be as follows:
private userOnline findUserOnlineWithUsername(String username) {
Iterator<userOnline> it = online.iterator();
onlineUser olu = null;
while(it.hasNext()) {
olu = it.next();
if (olu.userName.equals(username)) { return olu;}
}
return null;
}
Iterate over the list to find the index of the element you are interested in:
int idx = -1;
for (int i = 0; i < online.size(); i++) {
if(online.get(i).userName.equals("MyUsername"))
{
idx = i;
}
}
Use this index to remove the relevant element:
if(idx != -1) {
online.remove(online[idx]);
}
This would only remove the first occurrence. You could put this code into a function and call repeatedly to find all occurrences.
Your code is asking to remove a String from a List of UserOnlines, you need to use the object reference for the remove(Object o) method, or you need to find out the index of the object you wish to remove and use the remove(int index) method. How are you adding your objects to the list? If you're using the list itself as a reference you'll need to create your own method to define what object "MyUserName" is supposed to be.

Comparing two JsonArray nodes in Java

I have a method that gets two Json nodes that should be Json array nodes of different sizes.
I need to check if ArrayA contains all the elements of ArrayB. How do I do that?
private boolean isContains (JsonNode ArrayA, JsonNode ArrayB) {
if (ArrayA.isArray() && ArrayB.isArray()) {
// Here goes the missing code.
}
}
The JSON Patch reverse part might do what you are looking for.
See: https://github.com/fge/json-patch#json-diff-factorization
Edit:
It is as easy as:
JsonNode diff = JsonDiff.asJson(first, second);
And than you can check whether diff contains removes or adds or both.
There seems to be no inbuilt method I can see, but JsonNode implements Iteratable so you can loop through both and do a compare. Something along the lines of:
boolean matches = true;
for (JsonNode nodeB : arrayB)
{
boolean matchesInternal = false;
for (JsonNode nodeA : arrayA)
{
if (nodeA.equals(nodeB))
{
matchesInternal = true;
break;
}
}
if (!matchesInternal) {
matches = false;
break;
}
}
return matches;
You can use zjsonpatch library, which presents the diff information in accordance with RFC 6902 (JSON Patch). Its very easy to use. Please visit its description page for its usage.
This library is better than fge-json-patch (which was mentioned in above answer) because it can detect correctly items being inserted/removed from arrays.
For those who faced the same problem but prefer more flat code. You can use the Apache Commons's IterableUtils.toList() to convert the ArrayNode#elements() to List and then perform List#containsAll() operation to check whether they contain the same elements. It will look like this:
sourceArray.size() == targetArray.size() && IteratorUtils.toList(sourceArray.elements()).containsAll(IteratorUtils.toList(targetArray.elements()))

List to String using toString() in java

I'm having ArrayList Contains of String. I would like to check whether the character is present in the arraylist. I'm using the following code.
if(list.toString.contains(char))
{
// enter code here
}
Can i use this toString() method. What is the drawback?
It would be a really bad idea to use List.toString() and search that. Your code should probably look something like this :
Iterator it = list.getIterator();
char searchChar = 'S';
while (it.hasNext())
{
String s = (String) it.next();
if ( s.contains(searchChar) )
{
//Found the char!
}
}
No you cannot go ahead with arraylist.toString(), as it will not provide string representation of contents in String.
Better approach is to iterate over list and check, as below.
for(String detail:listString){
if(detail.contains('X')) //replace 'X' with your character
{
// do somethng
}
}
Try this,
Arrays.toString(inputList.toArray()).contains(searchValue);
list.toString() gives you a string representation of a list and thus it contains more characters then just the concatenated list elements
[stringElement1, stringElement2, ... ]
Therefore your approach will not work if the character you are looking for is , , , [ or ].
And keep in mind that this string representation is implementation specific. It might not work for other list implementations than ArrayList
I would recommend to write a method linke this:
private boolean listElementContains(List<String> list, String subString){
for(String element : list){
if(element.contains(subString)){
return true;
}
}
return false;
}
You can call toString() on any Java Object. List is an Object which contains (you guessed it) a list of other Objects. Therefore, you can also call toString() on each Object contained within the List. You should read about inheritance in Java.
In your particular case, you have a List of Strings. What you actually want to do is check each String in the List to see if the String contains a particular character. Topics you may want to read about include iteration, for loops, and for each loops.
If I understand this correctly, your code would look like this:
List<String> strings = new ArrayList<>();
//add strings to list
for (String string : strings) {
//Look for some character c
if (string.indexOf(c) >= 0) {
return true;
}
}
return false;
On the matter of list.toString, that simply returns a representation of the object as a string; it has nothing to do with the contents. Think of it like a label on a box of stuff that says "Junk." The box is labeled Junk, but you have no idea what's in it.
What's nearly certain is that toString will return a nonsense label for the object in memory. So to get at what's inside, you need to loop through the contents as shown above.
if(list.toString.contains(char))
String's contains() method won't take char as param, instead check with indexOf
Your code works, with little modifications.
A small example here:
List<String> list= new ArrayList<>();
list.add("test");
list.add("test2");
if (list.toString().indexOf('t') > -1) // True
{
System.out.println("yes there");
}
Note:
As a workaround, Make an char array and add your char in to that array and then use contains method.

Java: Retrieving an element from a HashSet

Why cannot I retrieve an element from a HashSet?
Consider my HashSet containing a list of MyHashObjects with their hashCode() and equals() methods overridden correctly. I was hoping to construct a MyHashObject myself, and set the relevant hash code properties to certain values.
I can query the HashSet to see if there "equivalent" objects in the set using the contains() method. So even though contains() returns true for the two objects, they may not be == true.
How come then there isn’t any get() method similar to how the contains() works?
What is the thinking behind this API decision?
If you know what element you want to retrieve, then you already have the element. The only question for a Set to answer, given an element, is whether it contains() it or not.
If you want to iterator over the elements, just use a Set.iterator().
It sounds like what you're trying to do is designate a canonical element for an equivalence class of elements. You can use a Map<MyObject,MyObject> to do this. See this Stack Overflow question or this one for a discussion.
If you are really determined to find an element that .equals() your original element with the constraint that you must use the HashSet, I think you're stuck with iterating over it and checking equals() yourself. The API doesn't let you grab something by its hash code. So you could do:
MyObject findIfPresent(MyObject source, HashSet<MyObject> set)
{
if (set.contains(source)) {
for (MyObject obj : set) {
if (obj.equals(source))
return obj;
}
}
return null;
}
It is brute-force and O(n) ugly, but if that's what you need to do...
You can use HashMap<MyHashObject, MyHashObject> instead of HashSet<MyHashObject>.
Calling containsKey() on your "reconstructed" MyHashObject will first hashCode() - check the collection, and if a duplicate hashcode is hit, finally equals() - check your "reconstructed" against the original, at which you can retrieve the original using get()
Complexity is O(1) but the downside is you will likely have to override both equals() and hashCode() methods.
It sounds like you're essentially trying to use the hash code as a key in a map (which is what HashSets do behind the scenes). You could just do it explicitly, by declaring HashMap<Integer, MyHashObject>.
There is no get for HashSets because typically the object you would supply to the get method as a parameter is the same object you would get back.
If you know the order of elements in your Set, you can retrieve them by converting the Set to an Array. Something like this:
Set mySet = MyStorageObject.getMyStringSet();
Object[] myArr = mySet.toArray();
String value1 = myArr[0].toString();
String value2 = myArr[1].toString();
The idea that you need to get the reference to the object that is contained inside a Set object is common. It can be archived by 2 ways:
Use HashSet as you wanted, then:
public Object getObjectReference(HashSet<Xobject> set, Xobject obj) {
if (set.contains(obj)) {
for (Xobject o : set) {
if (obj.equals(o))
return o;
}
}
return null;
}
For this approach to work, you need to override both hashCode() and equals(Object o) methods
In the worst scenario we have O(n)
Second approach is to use TreeSet
public Object getObjectReference(TreeSet<Xobject> set, Xobject obj) {
if (set.contains(obj)) {
return set.floor(obj);
}
return null;
}
This approach gives O(log(n)), more efficient.
You don't need to override hashCode for this approach but you have to implement Comparable interface. ( define function compareTo(Object o)).
One of the easiest ways is to convert to Array:
for(int i = 0; i < set.size(); i++) {
System.out.println(set.toArray()[i]);
}
If I know for sure in my application that the object is not used in search in any of the list or hash data structure and not used equals method elsewhere except the one used indirectly in hash data structure while adding. Is it advisable to update the existing object in set in equals method. Refer the below code. If I add the this bean to HashSet, I can do group aggregation on the matching object on key (id). By this way I am able to achieve aggregation functions such as sum, max, min, ... as well. If not advisable, please feel free to share me your thoughts.
public class MyBean {
String id,
name;
double amountSpent;
#Override
public int hashCode() {
return id.hashCode();
}
#Override
public boolean equals(Object obj) {
if(obj!=null && obj instanceof MyBean ) {
MyBean tmpObj = (MyBean) obj;
if(tmpObj.id!=null && tmpObj.id.equals(this.id)) {
tmpObj.amountSpent += this.amountSpent;
return true;
}
}
return false;
}
}
First of all, convert your set to an array. Then, get the item by indexing the array.
Set uniqueItem = new HashSet();
uniqueItem.add("0");
uniqueItem.add("1");
uniqueItem.add("0");
Object[] arrayItem = uniqueItem.toArray();
for(int i = 0; i < uniqueItem.size(); i++) {
System.out.println("Item " + i + " " + arrayItem[i].toString());
}
If you could use List as a data structure to store your data, instead of using Map to store the result in the value of the Map, you can use following snippet and store the result in the same object.
Here is a Node class:
private class Node {
public int row, col, distance;
public Node(int row, int col, int distance) {
this.row = row;
this.col = col;
this.distance = distance;
}
public boolean equals(Object o) {
return (o instanceof Node &&
row == ((Node) o).row &&
col == ((Node) o).col);
}
}
If you store your result in distance variable and the items in the list are checked based on their coordinates, you can use the following to change the distance to a new one with the help of lastIndexOf method as long as you only need to store one element for each data:
List<Node> nodeList;
nodeList = new ArrayList<>(Arrays.asList(new Node(1, 2, 1), new Node(3, 4, 5)));
Node tempNode = new Node(1, 2, 10);
if(nodeList.contains(tempNode))
nodeList.get(nodeList.lastIndexOf(tempNode)).distance += tempNode.distance;
It is basically reimplementing Set whose items can be accessed and changed.
If you want to have a reference to the real object using the same performance as HashSet, I think the best way is to use HashMap.
Example (in Kotlin, but similar in Java) of finding an object, changing some field in it if it exists, or adding it in case it doesn't exist:
val map = HashMap<DbData, DbData>()
val dbData = map[objectToFind]
if(dbData!=null){
++dbData.someIntField
}
else {
map[dbData] = dbData
}

Categories