I'm a Java beginner, so please bare with possibly silly or trivial questions.
I have two collections (array lists or hashtables) and I want to compare each and every element of the first collection to each and every element of the second collection.
I wrote the following code, but this only compares element 1 of the first collection to element 1 of the second collection, element 2 of the first collection with element 2 of the second collection, etc., so I am missing most of the comparisons that I want to make. Can you please help me out?
public class IteratorDemo_1 {
public static void main(String args[]) {
// Create two array lists:
ArrayList alLetters = new ArrayList();
ArrayList alNumbers = new ArrayList();
// Add elements to the array lists:
alLetters.add("C");
alLetters.add("B");
alLetters.add("Z");
alLetters.add("X");
alNumbers.add("1");
alNumbers.add("6");
alNumbers.add("3");
alNumbers.add("7");
// Use iterator to display the contents of 'al':
System.out.println("Original contents of 'alLetters': ");
Iterator itrL = alLetters.iterator();
System.out.println("Original contents of 'alNumbers': ");
Iterator itrN = alNumbers.iterator();
while(itrL.hasNext()){
while(itrN.hasNext()){
Object elementL = itrL.next();
Object elementN = itrN.next();
boolean result = elementL.equals(elementN);
System.out.println(result);
System.out.println(elementL + " ");
System.out.println(elementN + " ");
}
}
System.out.println();
}
}
while(itrL.hasNext()){
Object elementL = itrL.next();
while(itrN.hasNext()){
Object elementN = itrN.next();
boolean result = elementL.equals(elementN);
System.out.println(result);
System.out.println(elementL + " ");
System.out.println(elementN + " ");
}
itrN = alNumbers.iterator();
}
Try the following:
while(itrL.hasNext()){
Object elementL = itrL.next();
Iterator itrN = alNumbers.iterator();
while(itrN.hasNext()){
Object elementN = itrN.next();
boolean result = elementL.equals(elementN);
System.out.println(result);
System.out.println(elementL + " ");
System.out.println(elementN + " ");
}
}
Related
My Java routine should find a String from one ArrayList as a char sequence of another ArrayList String.
If I search for a String item from the source ArrayList in the target ArrayList it works.
If the target ArrayList item has more alphanumeric literals I tried to find the wanted part by using a char sequence.
Short Example in Words:
ArrayList_A Items: "A0B","C1D","E2F"
ArrayList_B Item: "A0B"
Result: Item B found in ArrayList_A Items (works)
ArrayList_A Items: "A0B/C1D","E2F"
ArrayList_B Item: "A0B"
Result: Item B found in ArrayList_A Items (this is what I want additionally)
Below is my partly working code. Can anyone please fix it so that I can learn from the solution?
import java.util.ArrayList;
public class Checking {
static void checkValues () {
ArrayList<String> arrayListA = new ArrayList();
arrayListA.add("A0B/C1D");
arrayListA.add("E2F");
System.out.println("\narrayListA: " + arrayListA);
int sizeLA = arrayListA.size();
System.out.println("arrayListA Length:" + sizeLA);
ArrayList<String> arrayListB = new ArrayList();
arrayListB.add("A0B");
arrayListB.add("E2F");
System.out.println("\narrayListB: " + arrayListB);
int sizeLB = arrayListB.size();
System.out.println("arrayListB Length:" + sizeLB);
ArrayList<String> arrayListFound = new ArrayList();
//Something must be fixed here...
arrayListB.stream().forEach((searchStr) -> {
System.out.print("\nstr Search Item is: " + searchStr);
if(arrayListA.contains((CharSequence)searchStr)){
System.out.print(" - found!" );
arrayListFound.add((String) searchStr);
}
else {
System.out.print(" - not found");
}
});
System.out.println("\n\narrayListFound Items: " + arrayListFound);
int sizeListFound = arrayListFound.size();
System.out.println("sizeListFound Length :" + sizeListFound);
System.out.println("Expected to be fully found in arrayListFound: " + arrayListB);
}
public static void main(String[] args) {
checkValues();
}
}
At first you should use functional style programming. forEach() doesn't allow you more than standard for (...)
For exact matching
ArrayList<String> arrayListFound = arrayListB.stream()
.filter(arrayListA::contains)
.collect(Collectors.toList());
For substring matcing
ArrayList<String> arrayListFound = arrayListB.stream()
.filter(itemB -> arrayListA.stream()
.matchAny(itemA -> itemA.contains(itemB))
)
.collect(Collectors.toList());
You may stream over both collections and use String#contains instead of List#contains.
It will add all the corresponding String objects from B contained in A to arrayListFound
arrayListB.stream().forEach(b ->
arrayListA.stream().forEach(a -> {
if (a.contains(b)){
arrayListFound.add(b);
}
}
));
if(arrayListA.contains((CharSequence)searchStr)){
System.out.print(" - found!" );
arrayListFound.add((String) searchStr);
}
This snippet says, "if my list contains exactly this string, it's found". But your String A0B, isn't the same as A0B/C1D. Iterating over both lists and checking the contains method of String and not of ArrayList, you'll find what you need. E.g:
arrayListB.stream().forEach((searchStr) -> {
System.out.print("\nstr Search Item is: " + searchStr);
arrayListA.stream().forEach((sndStr) -> {
if (sndStr.contains(searchStr) || searchStr.contains(sndStr)) {
System.out.print(" - found!");
arrayListFound.add((String) searchStr);
} else {
System.out.print(" - not found");
}
});
});
An alternative solution that only slightly modifies your implementation is as follows.
arrayListB.stream().forEach((searchStr) -> {
if(arrayListA.stream().anyMatch(str -> str.contains((CharSequence)searchStr))){
System.out.print(" - found!" );
arrayListFound.add((String) searchStr);
}
else {
System.out.print(" - not found");
}
});
i. We can use anyMatch which would be perform better than foreach.
ii. Here we are checking if there exists any string in arrayListA which would have searchStr from arrayListB as the sub-string.
To do it in purely functional style without mutating the arrayListFound list, the following approach can be adopted:
Predicate<String> isInArrayA = searchStr-> arrayListA.stream().anyMatch(str -> str.contains(searchStr));
arrayListFound = (ArrayList<String>) arrayListB.stream()
.filter(isInArrayA)
.collect(Collectors.toList());
I am working with Arraylist of objects.
while i already succeeded in delete values from Arraylist while they are numeral.
i'm having trouble delete from arraylist while they are String
here is the example :
public class ArrayListDemo {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Namer> arrlist = new ArrayList<Namer>( );
// use add() method to add values in the list
arrlist.add(new Namer("1","A","G"));
arrlist.add(new Namer("2","E","G"));
arrlist.add(new Namer("3","F","G"));
System.out.println("Size of list: " + arrlist.size());
// let us print all the values available in list
for (Namer value : arrlist) {
System.out.println("age = " + value.age);
}
arrlist.remove("3");
System.out.println("Now, Size of list: " + arrlist.size());
for (Namer value : arrlist) {
System.out.println("age = " + value.age); //System.out.println("Value = " + value);
}
}
}
and the result of running it proof it doesnt deleted the spesific row
i need to delete if with String and cant use number as "Key" .
Size of list: 3
age = 1
age = 2
age = 3
Now, Size of list: 3
age = 1
age = 2
age = 3
what can i make it to work with String in order to delete ?
if that's help
this is the object of arrayList
public class Namer
{
// instance variables - replace the example below with your own
public String age;
public String name;
public String L_name;
public Namer(String a, String na , String Lname)
{
// initialise instance variables
age =a;
name=na;
L_name=Lname;
}
}
You have Namer objects in your ArrayList, not Strings. When you call remove("3"), the ArrayList will look for an object that returns true when equals is called on it with "3". Of course, no String will compare equals with any Namer.
You must do the comparison yourself with the name field, and remove the appropriate item. This can be done with an Iterator and its remove method.
You have to use the object or the index to remove and you are not using either ...
Try this code :
arrlist.remove(2);
or
// create an empty array list with an initial capacity
ArrayList<Namer> arrlist = new ArrayList<Namer>( );
Namer namer1= new Namer("1","A","G");
Namer namer2= new Namer("2","E","G");
Namer namer3= new Namer("3","F","G");
// use add() method to add values in the list
arrlist.add(namer1);
arrlist.add(namer2);
arrlist.add(namer3);
arrlist.remove(namer3);
The method arrlist.remove(idx) takes as paramenter the (interger) index of the element to be removed from the array. There's no such thing as a "key" for ArrayLists.
You probably want to use java.util.Map<Integer,Namer>.
I have two collections where both the keys and the values are strings. I need the collections to be ordered, so I decided to use "TreeMap" to keep the ordering.
I want to:
1) print out the two collections, 'garList' and 'noGarList', respectively;
2) compare each and every element of the first collection with each and every element of the second collection;
3) remove from the first collection ('garList') those elements that appear in the second collection ('noGarList') as well.
I wrote the following code to do these 3 tasks:
public class TryTask_A_copy {
public static void main(String[] args) {
// First collection:
TreeMap<String, String> garList = new TreeMap<>();
// Second collection:
TreeMap<String, String> noGarList = new TreeMap<>();
// Fill the "Properties" obj for 'Gar':
garList.put("Gar_1", "rotura de lunas");
garList.put("Gar_2", "arbitraje de ley");
garList.put("Gar_3", "Adaptación del hogar");
// Fill the "Properties" obj for 'noGar':
noGarList.put("noGar_1", "rotura de lunas");
noGarList.put("noGar_2", "reembolso total");
noGarList.put("noGar_3", "Adaptación del coche");
// Get a set of the entries:
Set garSet = garList.entrySet();
Set noGarSet = noGarList.entrySet();
// Def strings needed for the comparison:
String strGar;
String strNoGar;
// Get an iterator:
Iterator i_gar = garSet.iterator();
Iterator i_noGar = noGarSet.iterator();
// Display 'Gar' elements:
while(i_gar.hasNext()){
String me_Gar = (String)i_gar.next(); // Exception in thread "main" java.lang.ClassCastException: java.util.TreeMap$Entry cannot be cast to java.lang.String
strGar = (String) i_gar.next();
System.out.println(strGar + " : " + garList.get(strGar) + ".");
}
System.out.println();
// Display 'noGar' elements:
while(i_noGar.hasNext()){
String me_noGar = (String)i_noGar.next();
strNoGar = (String) i_noGar.next();
System.out.println(strNoGar + " : " + garList.get(strNoGar) + ".");
}
// Get new iterators:
Iterator itr_gar = garSet.iterator();
Iterator itr_noGar = noGarSet.iterator();
// Compare elements from 'Gar' list with elements from 'noGar' list
// and remove those elements from 'Gar' list that appear in 'noGar' list as well:
while(itr_gar.hasNext()){
strGar = (String) itr_gar.next();
while(itr_noGar.hasNext()){
String str1 = garList.get(strGar);
strNoGar = (String) itr_noGar.next();
String str2 = noGarList.get(strNoGar);
boolean result = str1.equalsIgnoreCase(str2);
System.out.println(strGar + " : " + str1 + ".");
System.out.println(strNoGar + " : " + str2 + ".");
System.out.println(result);
System.out.println();
// if an element appears in both lists, then remove this element from "Gar" list:
if(result != true){
} else {
Object garList_new = garList.remove(strGar);
System.out.println("Removed element: " + garList_new);
System.out.println();
}
}
itr_noGar = noGarSet.iterator();
}
}
}
But I get:
Exception in thread "main" java.lang.ClassCastException:
java.util.TreeMap$Entry cannot be cast to java.lang.String" at line 51
(see comments).
I understand that the elements of my two TreeMap objects are of "Map Entry" type and cannot be converted to "String" type, is that correct?
But then how can I get an ordered collection where both the keys and the values are Strings?
Writing something like garSet.removeAll(noGarSet) does not work because this would imply that both key AND value coincide. But in my case I have some of the values in the two collections coinciding while having different keys.
So I need a solution to the following: have an ordered collection where both keys and values are Strings and where values can be compared and removed.
Can you please help me out with this?
I'm a little unclear on just what you are trying to achieve but if you want to remove based on keys then just do:
garSet.removeAll(noGarSet);
Your code in general seems to be far more complex than it needs to be for what you are trying to achieve. For example to print all the Strings in the Map just do:
for (Entry<String, String> entry: garMap.entrySet()) {
System.out.println(entry.key() + " : " + entry.value() + ".");
}
If you do:
map1.keySet().removeAll(map2.keySet())
then that will remove all the duplicates based on key.
map1.values().removeAll(map2.values())
will remove all duplicates based on value.
map1.entryset().removeAll(map2.entrySet())
will remove all duplicates based on key/value pairs.
I have an instance of ArrayList named array.
When I parse some JSON data it will store it all in array.
When I do a System.out.println(array); it will list a long list of items, around 30, but when I write System.out.println(array.size); it will give the value one.
How come it only gives me the value 1 when the list contains at least 30 values?
My code for this:
public void setLocationName (String name) {
array = new ArrayList<String>();
array.add(name);
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}
public String[] getLocationName() {
String tArray[] = null;
for (int i = 0; i < array.size(); i++){
System.out.println(i);
tArray = array.toArray(new String[i]);
}
return tArray;
}
}
The long list :
[Brunnsparken, Göteborg]
[Brunnsgatan, Göteborg]
[Brunnslyckan, Lerum]
[Brunnsbotorget, Göteborg]
[Brunnsnäs, Ulricehamn]
[Brunnshult, Mellerud]
[Brunnsdal, Skövde]
[Brunns skola, Ulricehamn]
[Brunnsgården, Kungälv]
[Brunns kyrka, Ulricehamn]
[Boråsparken, Borås]
[Stadsparken, Ulricehamn]
[Lysekilsparken, Lysekil]
[Mössebergsparken, Falköping]
[Dalaborgsparken, Vänersborg]
[Rösparken, Åmål]
[Lillhagsparken Norra, Göteborg]
[Lillhagsparken Södra, Göteborg]
[Sylte Ryrbäcksparken, Trollhättan]
[Skogstomtsparken, Borås]
[Svinesundsparken, Norge]
[Håjumsparken, Trollhättan]
[Eriksdalsparken, Bollebygd]
[Fridhemsparken, Lidköping]
My result will be that only one item from the list will be returned in the tArray but I wanna return the whole list.
How to solve this?
Java doesn't understand Json and basically what you're doing is add a string to an array
this.array.add(name); ---> add one value to the array, therefore the size is just one
you may need to use a specific Json library to parse the data in to an java arraylist.
regards
Look like you need to parse the String into pairs.
Looks to me like a Map might be the most appropriate structure to store the data in - I presume the first part from the value is unique.
Regex is probably the best approach to parsing the data:
public static void main(String[] args) {
final String data = "[Brunnsparken, Göteborg]\n"
+ "[Brunnsgatan, Göteborg]\n"
+ "[Brunnslyckan, Lerum]\n"
+ "[Brunnsbotorget, Göteborg]\n"
+ "[Brunnsnäs, Ulricehamn]\n"
+ "[Brunnshult, Mellerud]\n"
+ "[Brunnsdal, Skövde]\n"
+ "[Brunns skola, Ulricehamn]\n"
+ "[Brunnsgården, Kungälv]\n"
+ "[Brunns kyrka, Ulricehamn]\n"
+ "[Boråsparken, Borås]\n"
+ "[Stadsparken, Ulricehamn]\n"
+ "[Lysekilsparken, Lysekil]\n"
+ "[Mössebergsparken, Falköping]\n"
+ "[Dalaborgsparken, Vänersborg]\n"
+ "[Rösparken, Åmål]\n"
+ "[Lillhagsparken Norra, Göteborg]\n"
+ "[Lillhagsparken Södra, Göteborg]\n"
+ "[Sylte Ryrbäcksparken, Trollhättan]\n"
+ "[Skogstomtsparken, Borås]\n"
+ "[Svinesundsparken, Norge]\n"
+ "[Håjumsparken, Trollhättan]\n"
+ "[Eriksdalsparken, Bollebygd]\n"
+ "[Fridhemsparken, Lidköping]";
final Pattern pattern = Pattern.compile("\\[([^,]++),\\s++([^\\]]++)\\]");
final Matcher matcher = pattern.matcher(data);
final Map<String, String> items = new TreeMap<>();
while (matcher.find()) {
items.put(matcher.group(1), matcher.group(2));
}
for (final Entry<String, String> entry : items.entrySet()) {
System.out.println(entry);
}
}
Output from this:
Boråsparken=Borås
Brunns kyrka=Ulricehamn
Brunns skola=Ulricehamn
Brunnsbotorget=Göteborg
Brunnsdal=Skövde
Brunnsgatan=Göteborg
Brunnsgården=Kungälv
Brunnshult=Mellerud
Brunnslyckan=Lerum
Brunnsnäs=Ulricehamn
Brunnsparken=Göteborg
Dalaborgsparken=Vänersborg
Eriksdalsparken=Bollebygd
Fridhemsparken=Lidköping
Håjumsparken=Trollhättan
Lillhagsparken Norra=Göteborg
Lillhagsparken Södra=Göteborg
Lysekilsparken=Lysekil
Mössebergsparken=Falköping
Rösparken=Åmål
Skogstomtsparken=Borås
Stadsparken=Ulricehamn
Svinesundsparken=Norge
Sylte Ryrbäcksparken=Trollhättan
You can the access the items by looping (as above) or by getting values from the Map by key. The TreeMap I have used will sort the data by key, you can also use a LinkedHashMap to store the data in insertion order.
You could also store the items in a List of tuple like structures.
public void setLocationName (String name) {
array = new ArrayList<String>();
array.add(name);
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}
You are creating a new ArrayList each time you call this method:
array = new ArrayList<String>();
You could just remove the above line, however I suggest you rename the method as this is no longer a setter and you are in fact now adding to an existing list each time you call this method.
I suggest what you want to do is build your List before parsing to the setter, perhaps using a foreach loop (I'm not sure what kind of object you are working with) and simplify your setter (setLocationName) to accomodate.
So it would become:
public void setLocationName(ArrayList<String> names)
{
this.array = names;
System.out.println(array); //This return a long list
System.out.println(array.size()); //But this only return the value 1
}
How do I combine two Lists in Java?
The output so far is:
Firstname1
Firstname2
Firstname3
Lastname1
Lastname2
Lastname3
[[Firstname1, Firstname2, Firstname3], [Lastname1, Lastname2, Lastname3]]
I want the out put to be:
[Firstname1 Lastname1, Firstname2 Lastname2, Firstname3 Lastname3}
import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
List<String> peoplFname = Arrays.asList("Firstname1", "Firstname2", "Firstname3");
List<String> peoplLname = Arrays.asList("Lastname1", "Lastname2", "Lastname3");
Iterator<String> iterator = peoplFname.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
Iterator<String> iteratorx = peoplLname.iterator();
while(iteratorx.hasNext()) {
System.out.println(iteratorx.next());
}
HashSet peopleFullName = new HashSet();
peopleFullName.add(peoplFname);
peopleFullName.add(peoplLname);
System.out.println(peopleFullName.toString());
}
}
Use addAll instead of add, in order to add all elements from the list into your set.
Change your code to:
peopleFullName.addAll(peoplFname);
peopleFullName.addAll(peoplLname);
Update:
Based on the updated question, it looks like you want to combine corresponding elements from both lists. You're on the right track. You just need to iterate over both lists, join the first name with the last name and then add it to a result list:
List<String> peoplFname = Arrays.asList("Firstname1", "Firstname2", "Firstname3");
List<String> peoplLname = Arrays.asList("Lastname1", "Lastname2", "Lastname3");
Iterator<String> iterator = peoplFname.iterator();
Iterator<String> iteratorx = peoplLname.iterator();
List<String> peopleFullName = new ArrayList<String>();
while(iterator.hasNext() && iteratorx.hasNext()) {
String fullName = iterator.next() + " " + iteratorx.next();
peopleFullName.add(fullName);
}
System.out.println(peopleFullName);
Since Java is an Object Orientated Language I would use Object with two fields firstName and lastName. This would make adding the two list together much simpler. You can add a toString method to you new class which would produce the output you want.
If I understand correctly, what you want is to concatenate the elements from both lists:
List<String> fullNames = new ArrayList<String>(firstNames.size());
for (int i = 0; i < firstNames.size(); i++) {
fullNames.add(firstNames.get(i) + " " + lastNames.get(i));
}
Or, using iterators (which would be important if the lists were long lists not backed by an array):
List<String> fullNames = new ArrayList<String>(firstNames.size());
Iterator<String> lastNameIterator = lastNames.iterator();
for (Iterator firstNameIterator = firstNames.iterator(); firstNameIterator.hasNext();) {
String firstName = firstNameIterator.next();
String lastName = lastNameIterator.next();
fullNames.add(firstName + " " + lastName);
}
That said, I agree with Peter's answer: you should use a Person object with two properties: firstName and lastName.
Side note: I renamed your variables to make the code much more readable.
ArrayList<String> peopleFullNames = new ArrayList<String>();
for(i = 0; i < peopleFName.length; i++){
peoplNames.add(peopleFName.get(i) + " " + peopleLName.get(i));
}
Basically, this will create an ArrayList (or alternatively, you can create an array since you know the size) and then add the names to it one by one, combing the strings from both lists as you do it.
If you want to combine Firstname1 -> Lastname1; Firstname2 -> Lastname2....
You should do an simple for:
String[] fullName = new String[peoplFname.size()];
for(int i = 0; i < peoplFname.size(); i++)
{
fullName[i] = peopleFname.get(i)+" "+peopleLname.get(i);
}
Considering that peopleFname and peopleLname have the same number of elements.
If you want to make all possible name combinations, you should put an while inside the other one. So for the first name, all the last names will be iterated, and it'll happens for all the first names:
ArrayList<String> allCombinations = new ArrayList<String>();
Iterator<String> iterator = peoplFname.iterator();
while(iterator.hasNext()) {
Iterator<String> iteratorx = peoplLname.iterator();
while(iteratorx.hasNext()) {
allCombinations.add(iterator.next()+" "+iteratorx.next());
}
}