Get unique List elements based on a substring - java

I have an ArrayList(String) which contains a list of formatted dates like this:
element 1: "2012-5-1"
element 2: "2012-8-10"
element 3: "2012-12-5"
element 4: "2013-12-21"
element 5: "2013-12-13"
element 6: "2014-5-8"
What is the most efficient/framework way to create another list or normal primitive array that contains the unique year entries? For example my new list would contain:
element 1: "2012"
element 2: "2013"
element 3: "2014"

Try this
ArrayList<String> yearsOnlylist = new ArrayList<String> ();
for(String s : elements) {
String yearExtracted = s.substring(0,4);
yearsOnlylist.add(yearExtracted);
}
Where elements is the name of your list of date in the extended form.
Using as destination list
LinkedList<String> yearsOnlylist = new LinkedList<String> ();
instead of an ArrayList could sightly improve the conversion efficiency (because the add is O(1) in LinkedList) but access a specific position in a second time, has a lower efficiency (O(n) vs O(1)).

Just add them to a Set and convert it to a list:
Set<String> unique = new HashSet<String>();
for (String element : elements) {
set.put(element.substring(0,4));
}
List<String> uniqueList = new ArrayList<String>();
uniqueList.addAll(unique);

Iterate through your array list and take a substring of the first 4 characters of each member of the array list.
Add that substring to a set implementation such as a HashSet, which will give you what you want.

public List<String> trimmer(List<String> x) {
Log.e("", Integer.toString(x.size()));
for (int i = 0; i < x.size(); i++) {
String s = x.get(i).toString();
String a = s.substring(6);
Log.e("after trim is?", a);
x.remove(i);
x.add(i, a);
}
// check if the element got added back
Log.e("Trimmer function", x.get(1));
return x;
}
This will help you hopefully!

Related

a list of strings in Java

I have a question about setting the value to the list of strings in Java.
For example, if you have a list of strings called names, how would you set the 3rd name to the value "San Diego"?
I tried names.add(2, "San Diego") but it's not working.
Thanks so much for the help!
To update the already existing value use names.set(2,"String");
names.add(2, "San Diego") will add a new element at the 3rd position (index 2), but it will only work if the List already contains at least 2 elements.
names.set(2, "San Diego") will set the 3rd element (at index 2) to the required value, but it will work only if the List already contains at least 3 elements.
To obtain the 3rd element, you should use names.get(2) (again, the List must contain at least 3 elements for this to work).
If you want to replace an existing item in a list, you have to use set instead of add
names.set(2,"San Diego");
In here 2 means the index, counting from 0.
Then is the String you want to add
If you want to read values from the list you can use get
String value = names.get(2);
it will work if the List already contains at least 2 elements.
names.add(2, "San Diego") it will override the 3rd element or at index 2.
it is always safe to use
names.set(2, "San Diego") it will set the 3rd value or at index 2 if the list contains at least 3 elements.
Otherwise, it will throw IndexOutOfBoundsException: exception.
Here are the basic operation you can perform there are plenty of operation you can perform.
One advice try try and try dont give up.
here the is link for java dock for your reference
Java doc for List
package com.varun.list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListTest {
public static void main(String[] args) {
//Create array list
List < String > names = new ArrayList < String > ();
//Create few names
String sam = "Sam";
String jamie = "Jamie_dogLover";
String bucy = "The Bucky";
// add all names in the list
names.add(sam);
names.add(jamie);
names.add(bucy);
System.out.println("List values :" + names); //Output : List values :[Sam, Jamie_dogLover, The Bucky]
//Update the second index that is -> The Bucky, because list index starts from 0
names.set(2, "New Bucky");
System.out.println("New List values :" + names); //Output : New List values :[Sam, Jamie_dogLover, New Bucky]
//Lest say you want to remove the the 1st index that is jamie
names.remove(jamie);
System.out.println("Updates List values :" + names); //Output : Updates List values :[Sam, New Bucky]
//Let say you get a list of name from somewhere and you want to add into you existing list(names)
names.addAll(listOfDummyNames());
System.out.println("Updates List values with dummy names :" + names);
//Output : Updates List values with dummy names :[Sam, New Bucky, Name0, Name1, Name2, Name3, Name4]
//Let say you want to to remove all the name who has "name" String in it
Iterator < String > itr = names.iterator();
while (itr.hasNext()) {
String name = itr.next();
if (name.contains("Name")) {
itr.remove();
}
}
System.out.println("List after removing all name who has Name in it : " + names);
}
private static List < String > listOfDummyNames() {
List < String > dummyList = new ArrayList < String > ();
String name = "Name";
for (int i = 0; i < 5; i++) {
dummyList.add(name + i);
}
System.out.println("List of dummy Names :" + dummyList);
return dummyList;
}
}

Find match element in array

completely new to Java, I am trying to find the matched element from one array into another, cannot seem to understand how to do it. Here is a sample of how the data is and how far I've gotten:
In this code and after printing this line, this is how the data is:
ArrayList<String> all_accounts = new ArrayList<String>();
all_accounts.add(acc);
System.out.println("\nArray 1:" + all_accounts);
Result Array 1:
Array 1:[77737320]
Array 1:[88405378]
Array 1:[00056893]
Array 1:[10709816]
ArrayList<String> cancel_accounts = new ArrayList<String>();
cancel_accounts.add(cancel_acc);
System.out.println("\nArray 2:" + cancel_accounts);
Results from Array 2:
Array 2:[77737320]
Array 2:[]
Array 2:[]
Array 2:[]
Stack here, I still cant understand why it doesn't match:
String found = null;
for (String account: all_accounts) {
for (String canceled: cancel_accounts) {
System.out.println(canceled);
found = canceled;
}
System.out.println(found);
if(account.equals(found) ) {
System.out.println(account);
}
}
I need to find the matched element, 77737320 in this case.
Thanks for looking!
+1 for answer from user6904265
However, You need not create a new HashSet. You can use ArrayList.retainAll(). If you want to maintain the all_accounts list, create a new clone and use that instead.
You could implement this as intersection between sets:
Set<String> set_all_account = new HashSet<String>(all_accounts);
Set<String> set_cancel_accounts = new HashSet<String>(cancel_accounts);
set_all_account.retainAll(set_cancel_accounts);
set_all_account.forEach(x -> System.out.println("Element matched: "+x));
Or as said by kartiks in his comment you could call the retainAll method directly on the all_accounts array:
all_accounts.retainAll(cancel_accounts);
all_accounts.forEach(x -> System.out.println("matched element: "+x));
Pay attention with this solution because in this case retainAll applies directly on the ArrayList and modifies it (as you can see the final result is in the all_accounts array). Moreover duplicate elements remain in the result array.
Last implementation (if you want compute intersection and print the result all in one line, also this version keeps duplicate elements):
all_accounts.stream().filter(x -> cancel_accounts.contains(x)).forEach(x -> System.out.println("matched element: "+x));
You can loop through the one list and search the second list for each element in first.
for (String account: all_accounts) {
if (cancel_accounts.contains(account) {
// Match found - do something....
System.out.println(account);
}
}
Just add an equals check to your for - loops (will work even without List#contains method)
for(String account: all_accounts) {
System.out.println(account);
for(String canceled: cancel_accounts){
System.out.println(canceled);
if(account.equals(cancelled)){
//you've found first intersection, cancelled exists in both
System.out.println(canceled + " is the same as " + account);
}
}
}

How to obtain first 5 values from a LinkedHashSet?

I have a LinkedHashSet which contains multiple number of values.
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
I want to iterate through the set of values and display the first five values from the number of items stored in the set. I have used a for loop to iterate through values and display data, see below:
for (String sent : lhs) {
text.append(sent);
}
This outputs all the values stored in the LinkedHashSet. What alterations should I make to my code in order to only get the first 5 values from the set.
You can get your sets Iterator
Iterator<String> it = yourSet.iterator();
and move to next() element N times (assuming that it still hasNext() element)
int counter = 0;
while(it.hasNext() && counter++ < N){
String element = it.next();
...
}
int i = 0;
for (String sentences : lhs) {
if (i > 4) break;
text.append(sentences);
i++;
}
If you had java8, then I would suggest something like this:
yourLinkedHashSet
.stream()
.limit(5)
.forEachOrdered(text::append);
Explanation:
stream() will take one String after another from the collection
limit(5) will stop the calculations after five elements are processed
forEachOrdered(...) takes an action for each item, one after another
text::append is the action to be done per item
You can use subList without counter declaration
Iterator<String> iter = new ArrayList<>(lhs).subList(5, lhs.size())
.iterator();
while (iter.hasNext()) {
text.append(iter.next());
}

How to add element in List while iterating in java?

Say I have a List like:
List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");
While iterating through this list I want to add an element at the end of the list. But I don't want to iterate through the newly added elements that is I want to iterate up to the initial size of the list.
for (String s : list)
/* Here I want to add new element if needed while iterating */
Can anybody suggest me how can I do this?
You can't use a foreach statement for that. The foreach is using internally an iterator:
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException.
(From ArrayList javadoc)
In the foreach statement you don't have access to the iterator's add method and in any case that's still not the type of add that you want because it does not append at the end. You'll need to traverse the list manually:
int listSize = list.size();
for(int i = 0; i < listSize; ++i)
list.add("whatever");
Note that this is only efficient for Lists that allow random access. You can check for this feature by checking whether the list implements the RandomAccess marker interface. An ArrayList has random access. A linked list does not.
Iterate through a copy of the list and add new elements to the original list.
for (String s : new ArrayList<String>(list))
{
list.add("u");
}
See
How to make a copy of ArrayList object which is type of List?
Just iterate the old-fashion way, because you need explicit index handling:
List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
String s = myList.get(i);
// add items here, if you want to
}
You could iterate on a copy (clone) of your original list:
List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
// And if you have to add an element to the list, add it to the original one:
list.add("some element");
}
Note that it is not even possible to add a new element to a list while iterating on it, because it will result in a ConcurrentModificationException.
I do this by adding the elements to an new, empty tmp List, then adding the tmp list to the original list using addAll(). This prevents unnecessarily copying a large source list.
Imagine what happens when the OP's original list has a few million items in it; for a while you'll suck down twice the memory.
In addition to conserving resources, this technique also prevents us from having to resort to 80s-style for loops and using what are effectively array indexes which could be unattractive in some cases.
To help with this I created a function to make this more easy to achieve it.
public static <T> void forEachCurrent(List<T> list, Consumer<T> action) {
final int size = list.size();
for (int i = 0; i < size; i++) {
action.accept(list.get(i));
}
}
Example
List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
forEachCurrent(l, e -> {
l.add(e + "A");
l.add(e + "B");
l.add(e + "C");
});
l.forEach(System.out::println);
We can store the integer value while iterating in the list using for loop.
import java.util.*;
class ArrayListDemo{
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Enter the number of elements you wanna print :");
int n = scanner.nextInt();
System.out.println("Enter the elements :");
for(int i = 0; i < n; i++){
list.add(scanner.nextInt());
}
System.out.println("List's elements are : " + list);
/*Like this you can store string while iterating in java using forloop*/
List<String> list1 = new ArrayList<String>();
System.out.println("Enter the number of elements you wanna store or print : ");
int nString = scanner.nextInt();
System.out.println("Enter the elements : ");
for(int i = 0; i < nString; i++){
list1.add(scanner.next());
}
System.out.println("Names are : " + list1);
scanner.close();
}
}
Output:
Enter the number of elements you wanna print :
5
Enter the elements :
11
12
13
14
15
List's elements are : [11, 12, 13, 14, 15]
Enter the number of elements you wanna store or print :
5
Enter the elements :
apple
banana
mango
papaya
orange
Names are : [apple, banana, mango, papaya, orange]

removing duplicates from list of lists and preserving lists

I have an arrayList of arrayLists. Each inner arraylist contains some objects with the format (name.version) .
{ {a.1,b.2,c.3} , {a.2,d.1,e.1} , {b.3,f.1,z.1}....}
For example a.1 implies name = a and version is 1.
So i want to eliminate duplicates in this arraylist of lists. For me , two objects are duplicate when they have the same name
So essentially my output should be
{ { a.1,b.2,c.3},{d.1,e.1} ,{f.1 ,z.1} }
Note that i want the output in the exact same form (That is , i dont want a single list with no duplicates)
Can someone provide me with an optimal solution for this?
I can loop through each inner list and place the contents in the hashset. But two issues there, i cant get back the answer in
form of list of lists.Another issue is that when i need to override equals for that object , but i am not sure if that would
break other code. These objects are meaningfully equal if their names are same (only in this case. I am not sure that would
cover the entire spectrum)
Thanks
I used Iterator.remove() to modify the collection as you move through it.
// build your example input as ArrayList<ArrayList<String>>
String[][] tmp = { { "a.1", "b.2", "c.3" }, { "a.2", "d.1", "e.1" },
{ "b.3", "f.1", "z.1" } };
List<List<String>> test = new ArrayList<List<String>>();
for (String[] array : tmp) {
test.add(new ArrayList<String>(Arrays.asList(array)));
}
// keep track of elements we've already seen
Set<String> nameCache = new HashSet<String>();
// iterate and remove if seen before
for (List<String> list : test) {
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String element = it.next();
String name = element.split("\\.")[0];
if (nameCache.contains(name)) {
it.remove();
} else {
nameCache.add(name);
}
}
}
System.out.println(test);
Output
[[a.1, b.2, c.3], [d.1, e.1], [f.1, z.1]]
List<List<Pair>> inputs; // in whatever format you have them
List<List<Pair>> uniqued = new ArrayList<>(); // output to here
Set<String> seen = new HashSet<String>();
for (List<Pair> list : inputs) {
List<Pair> output = new ArrayList<>();
for (Pair p : list)
if (seen.add(p.getName()))
output.add(p);
uniqued.add(output);
}
Create a Set. Iterate over the list of lists' items. See if the item is in the Set. If it is already there, ignore it. If it isn't, add it to the Set and the list of lists.
Your method will return a new list of lists, not modify the old one. Modifying a list while iterating over it is a pain.

Categories