I have on ArrayList which contains data like this: 13-ITEM,14-ITEM,15-ITEMGROUP (with a hyphen (-) as the separator).
I want to split this list into two new ArrayLists:
ArrayList-1 containing the ids: [13,14,15..]
ArrayList-2 containing the Strings: [ITEM,ITEM,ITEMGROUP...]
I am new to Java. Thanks in advance.
You can use String#indexOf(char) to find the index in the String of the separator then use String#substring to extract the sub strings, as next:
List<String> list = Arrays.asList("13-ITEM","14-ITEM","15-ITEMGROUP");
List<String> list1 = new ArrayList<>(list.size());
List<String> list2 = new ArrayList<>(list.size());
for (String s : list) {
int index = s.indexOf('-');
// Add what we have before the separator in list1
list1.add(s.substring(0, index));
// Add what we have after the separator in list2
list2.add(s.substring(index + 1));
}
System.out.printf("List 1 = %s, List 2 = %s%n", list1, list2);
Output:
List 1 = [13, 14, 15], List 2 = [ITEM, ITEM, ITEMGROUP]
Split each entry and add the parts to the different lists. If the texts contain more -s, then use substring.
ArrayList<String> input = ...
List<String> output1 = new ArrayList<>(input.size());
List<String> output2 = new ArrayList<>(input.size());
for(String item:input){
String[] splitted = item.split("-");
output1.add(splitted[0]);
output2.add(splitted[1]);
}
You can use the following code
List<String> list = Arrays.asList("13-ITEM", "14-ITEM", "15-ITEMGROUP");
list.stream().map(p -> p.substring(0, p.indexOf('-'))).forEach(System.out::println);
list.stream().map(p -> p.substring(p.indexOf('-') + 1)).forEach(System.out::println);
If you split your concerns like this (each list is created using different logic), you will have a possibility to encapsulate code further. For example you can add some exception handling.
private static Function<String, String> getFunction() {
return new Function<String, String>() {
#Override
public String apply(String p) {
return p.substring(0, p.indexOf('-'));
}
};
}
Related
I want to merge two corresponding values of two different variables with comma separator in a row :
like
Plate Numbers(Output) : MH 35353, AP 35989, NA 24455, DL 95405.
There is two different variables one is plate State and another is plate Number, I want to merge them together with their corresponding values like 1st values of plate State with 1st value of plate Number after that comma then so on..
I tried this code snippet but didn't work :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
list1.addAll(list2);
use this :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
Iterator iterable = list2.iterator();
List<String> list3 =list1.stream()
.map(x->{
x= x+" "+((String) iterable.next());
return x;})
.collect(Collectors.toList());
String output = String.join(", ", list3);
System.out.println(output);
From ArrayList#addAll Javadoc:
Appends all of the elements in the specified collection to the end of this list[...]
This is not what you want, because you actually don't want to append the objects, you want to merge the String of the first list with the String from the second list. So in a sense, not merge the List but merge the objects (Strings) in the lists.
The easiest (most beginner friendly) solution would be to just create a simple helper method yourself, that does what you need.
Something like this:
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA");
list1.add("DL");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
ArrayList<String> combined = combinePlateNumbers(list1, list2);
System.out.println(combined);
}
private static ArrayList<String> combinePlateNumbers(List<String> list1, List<String> list2) {
ArrayList<String> result = new ArrayList<>();
if (list1.size() != list2.size()) {
// lists don't have equal size, not compatible
// your decision on how to handle this
return result;
}
// iterate the list and combine the strings (added optional whitespace here)
for (int i = 0; i < list1.size(); i++) {
result.add(list1.get(i).concat(" ").concat(list2.get(i)));
}
return result;
}
Output:
[MH 35353, AP 35989, NA 24455, DL 95405]
Consider the following code:
final Set<String> allPaths = new HashSet<String>();
for (final String path: paths) {
allPaths.add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));
MyData is some class I should not touch. It should get an ArrayList as an argument. Before this day, we used that way because we didn't care about the order, that is why we used Set (so there will not be duplicated). But now, I would like to keep the order of the elements, so after some research, I found out that I can use the data structure LinkedHashSet in order to do so. So I did:
final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
allPaths .add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));
Problem is, I'm not sure how to convert LinkedHashSet to ArrayList. Also, I thought of using ArrayList instead of LinkedHashSet so I won't have to convert it, but I'll have to iterate over the array (O(n)).
What good, clean and effiect way should I use?
Just use the public boolean addAll(Collection<? extends E> c) method, on the arrayList, it accepts any Collection.
You have your LinkedHashSet:
final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
allPaths .add(path);
}
and then do (you can use this even if mylist is not empty):
List<String> myList = new ArrayList<>();
mylist.addAll(allPaths);
or for even a simpler approach:
List<String> myList = new ArrayList<>(allPaths);
Why dont you just convert your paths to an LinkedHashSet like that (assuming that paths is a Collection?
final MyData d = new MyData(new ArrayList<>(new LinkedHashSet<>(paths)));
In case paths is an array, you can use Arrays.asList(paths) inside the conversion above
#TTaJTa4 you can use the code below as an example. Both ways are fine.
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;
public class ConvertLinkedHashSetToArrayList
{
public static void main(String[] args)
{
Set<String> testStrings = new LinkedHashSet<>();
testStrings.add("String 1");
testStrings.add("String 2");
testStrings.add("String 3");
testStrings.add("String 4");
testStrings.add("String 5");
System.out.println("** Printing LinkedHashSet: " + testStrings);
ArrayList<String> linkedHashSetToArrayList1 = new ArrayList<>(testStrings);
System.out.println("** Printing linkedHashSetToArrayList1:" +
linkedHashSetToArrayList1);
ArrayList<String> linkedHashSetToArrayList2 = new ArrayList<>();
linkedHashSetToArrayList2.addAll(testStrings);
System.out.println("** Printing linkedHashSetToArrayList2:" +
linkedHashSetToArrayList2);
}
}
Results are like:
** Printing LinkedHashSet: [String 1, String 2, String 3, String 4, String 5]
** Printing linkedHashSetToArrayList1:[String 1, String 2, String 3, String 4, String 5]
** Printing linkedHashSetToArrayList2:[String 1, String 2, String 3, String 4, String 5]
Follow the GitHub link for the full java project:
GitHub example
If paths is a collection you can get an array list no duplicates:
ArrayList<String> p = paths.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
If paths is an array:
ArrayList<String> p = Stream.of(paths).distinct().collect(Collectors.toCollection(ArrayList::new));
How I can group all lists in list which contains same exact value.
List<List<String>> list = new ArrayList<>();
This list contains list1 list2 list3 and etc....
I want to find if list1.get(0) is the same as list2.get(0) if no check with list3.get(0) and etc...
Later I need to group lists if I find the same values in each.
For example if true add list1 and list3 and others which were found to
List<List<String>> list2 = new ArrayList<>();
Now check with list2.get(0) if equal to others if yes group them and add them to anoter:
List<List<String>> list3 = new ArrayList<>();
What I achieved so far:
private static void findEqualLists(List<List<String>> list) {
int i = 0;
for (List<String> list1 : list) {
if (!Collections.disjoint(list1, list.get(i))) {
System.out.println(list1.get(0)+list.get(i).get(0));
}else{
System.out.println(list1.get(0)+list.get(i).get(0));
}
i++;
}
}
Value exmaple:
list = {{2017-02,jhon,car},{2017-03,maria,car},{2017-03, boy, car}, {2017-01,arya, car}, {2017-02, girl, car}}
Output:
Group1:
2017-03,maria,car
2017-03, boy, car
Group2:
2017-02,jhon,car
2017-02, girl, car
Group3
2017-01,arya, car
You want Collectors.groupingBy:
private static Map<String, List<List<String>>>
findEqualLists(List<List<String>> list) {
return list.stream().collect(Collectors.groupingBy(l -> l.get(0)));
}
The returned Map will use l.get(0) as a unique key, with each corresponding value being a List of only those Lists whose first element matches that key.
I am having three lists i.e., list1,list2,list3 my code works fine in getting the following list outputs:
o/p
Getting the list1 objects [man, animal, jackel]
Getting the list2 objects [1, 2, 3]
Getting the list3 objects [bobby, lion, dilip]
Now I am trying to get list4 as [man,1,bobby]
AND also list5 as [man,1,bobby , animal,2,lion , jackel,3,dilip]
Here is my code which gives the output of list1, list2, list3
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
List<String> list3 = new ArrayList<String>();
String splitstring="man,animal,jackel";
String splitid="1,2,3";
String splitscreenname="bobby,lion,dilip";
String[] arrsplitstring=splitstring.split(",");
String[] arrssplitid=splitid.split(",");
String[] arrsplitedscreenname=splitscreenname.split(",");
List<String> wordList = Arrays.asList(arrsplitstring);
List<String> wordid = Arrays.asList(arrssplitid);
List<String> wordscreenlist = Arrays.asList(arrsplitedscreenname);
for (int i=0;i<wordList.size();i++){
list1.add(wordList.get(i));
}
System.out.println("Getting the list1 objects " +list1 );
for(int i=0;i<wordid.size();i++){
list2.add(wordid.get(i));
}
System.out.println("Getting the list2 objects " +list2);
for (int i=0;i<wordscreenlist.size();i++){
list3.add(wordscreenlist.get(i));
}
System.out.println("Getting the list3 objects " +list3);
I'm Trying it by iteration of each list object but I almost lost in finding the solution.
Thanks in advance
What you want to do is iterate one of the Lists and add items from all 3 Lists to your new List.
What you probably want to actually do is have an Animal object of sorts, containing properties from the 3 original Lists.
Here's an example (note: Java 7 syntax here):
// initializing lists
List<String> animals = new ArrayList<>(
Arrays.asList(new String[]{"man", "animal", "jackal"})
);
List<Number> numbers = new ArrayList<>(
Arrays.asList(new Number[]{1, 2, 3})
);
List<String> names = new ArrayList<>(
Arrays.asList(new String[]{"bobby", "lion", "dilip"})
);
// sequential list of objects
List<Object> allObjects = new ArrayList<>();
// class describing an "animal", wrapping the 3 properties
class Animal {
String type;
Number number;
String name;
Animal(String type, Number number, String name) {
this.type = type;
this.number = number;
this.name = name;
}
// fancy String representation
#Override
public String toString() {
return String.format("Type: %s, Number: %d, Name: %s%n", type, number, name);
}
}
// list of Animals
List<Animal> allAnimals = new ArrayList<>();
// iterating the first list (arbitrary choice)
for (int i = 0; i < animals.size(); i++) {
// adding sequentially to objects list
allObjects.add(animals.get(i));
// TODO check for index out of bounds
allObjects.add(numbers.get(i));
allObjects.add(names.get(i));
// adding to animals list sequentially with 3 props each animal
allAnimals.add(new Animal(animals.get(i), numbers.get(i), names.get(i)));
}
// printing out values
System.out.println("All objects...");
System.out.println(allObjects);
System.out.println("All animals...");
System.out.println(allAnimals);
Output
All objects...
[man, 1, bobby, animal, 2, lion, jackal, 3, dilip]
All animals...
[Type: man, Number: 1, Name: bobby
, Type: animal, Number: 2, Name: lion
, Type: jackal, Number: 3, Name: dilip
]
The first one could be something like this:
List<String> list4 = new ArrayList<String>();
// Check the three lists have the same number of elements.
// If not, return (you have to show and error)
if (! (
(wordListIt.size() == wordidIt.size() )
&&
(wordidIt.size() == wordscreenlistIt.size() )
) ) return;
Iterator<String> wordListIt = wordList.iterator();
Iterator<String> wordidIt = wordid.iterator();
Iterator<String> wordscreenlistIt = wordscreenlist.iterator();
while (wordListIt.hasNext()) {
list4.add(wordListIt.next());
list4.add(wordidIt.next());
list4.add(wordscreenlistIt.next());
break; // exit the while, because you only want the first element.
}
The second one could be something like this:
List<String> list5 = new ArrayList<String>();
// Check the three lists have the same number of elements.
// If not, return (you have to show and error)
if (! (
(wordListIt.size() == wordidIt.size() )
&&
(wordidIt.size() == wordscreenlistIt.size() )
) ) return;
Iterator<String> wordListIt = wordList.iterator();
Iterator<String> wordidIt = wordid.iterator();
Iterator<String> wordscreenlistIt = wordscreenlist.iterator();
while (wordListIt.hasNext()) {
list5.add(wordListIt.next());
list5.add(wordidIt.next());
list5.add(wordscreenlistIt.next());
}
You need to iterate over the elements of each list to get your desired result..
List<String> list4 = new ArrayList<String>();
list4.add(list1.get(0));
list4.add(list2.get(0));
list4.add(list3.get(0));
List<String> list5 = new ArrayList<String>();
for(int ctr=0;ctr<list3.size();ctr++)
{
list5.add(list1.get(ctr));
list5.add(list2.get(ctr));
list5.add(list3.get(ctr));
}
I am having 1 -10 in different groups A,B and C.
For eg. A-1,A-2,A-3,B-4,C-5,B-6,A-7,C-8,A-9,A,10
I want to make group separately as A, B and C
A
1-3,
7,
9-10
B
4,
6
C
5,
8
can any one help me with logic..?
Guava will help you creating the Data Structure you need:
public static void main(final String[] args) {
String input = "A-1,A-2,A-3,B-4,C-5,B-6,A-7,C-8,A-9,A-10";
// create multimap
Map<String, Collection<Integer>> map=Maps.newTreeMap();
SortedSetMultimap<String, Integer> multimap = Multimaps.newSortedSetMultimap(
map, new Supplier<SortedSet<Integer>>() {
public SortedSet<Integer> get() {
return new TreeSet<Integer>();
}
});
//add data
Splitter entrySplitter = Splitter.on(',');
Splitter keyValueSplitter = Splitter.on('=');
for (String entry : entrySplitter.split(input)) {
Iterator<String> tokens = keyValueSplitter.split(entry).iterator();
multimap.put(tokens.next(), Integer.valueOf(tokens.next()));
}
// read data
for (Entry<String, Collection<Integer>> entry : map.entrySet()) {
System.out.println(entry.getKey()+":");
printMergedValues(entry.getValue());
}
}
private static void printMergedValues(Collection<Integer> value) {
// TODO implement this yourself
}
The only thing I left for you is to join the groups
Here is something to get you started:
String[] items = new String[] {
"A-1", "B-2", "A-5"
}
// This is the data structure that will receive the final data. The map key is the
// group name (e.g. "A" for item "A-15") and the map value is a list of numbers that
// have been found for that group. TreeMap is chosen because the groups will be sorted
// alphabetically. If you don't need that, you could also use HashMap.
Map<String, List<Integer>> groups = new TreeMap<String, List<Integer>>();
for (String item : items) {
// Split the item into the group and the number
String group = item.substring(0, 1);
String number = Integer.toString(item.substring(2));
// See if this group is already registered in our Map
List<Integer> groupData = groups.get(group);
if (groupData==null) {
groupData = new List<Integer>();
groups.put(group, groupData);
}
// Add the number to the data
groupData.add(number);
}
I assume here that your items are always in the form 1 letter dash number. If it is a bit more complicated than that, you'll want to have a look at regular expressions (see java class Pattern). This is not tested, I let you test it and handle the special cases.
This function will output for { "A-1", "A-2", "A-3", "B-2", "A-5" }:
A -> {1, 2, 3, 5}
B -> {2}
You'll need to process the resulting number lists if you want to merge consecutive numbers, but that should not be too difficult if you think about it a little while.
I'd go this way:
String[] input = {"A-1","A-2","A-3","B-4","C-5","B-6","A-7","C-8","A-9"};
Map<String, Set<Integer>> result = new HashMap<String, Set<Integer>>();
String[] inputSplit;
String group;
Integer groupNumber;
for (String item : input)
{
inputSplit = item.split("-");
group = inputSplit[0];
groupNumber = Integer.valueOf( inputSplit[1] );
if ( result.get(group) == null ) { result.put(group, new HashSet<Integer>()); }
result.get(group).add(groupNumber);
}
for (Map.Entry entry : result.entrySet())
{
System.out.println( entry.getKey() + ":" + entry.getValue() );
}