How to cast ArrayList<String> to String - java

This is my code:
ArrayList<String> contentArray = new ArrayList<String>();
for(HashMap<ArrayList<String>, String> subTopicsEntry : subTopics){
contentArray = (ArrayList<String>) subTopicsEntry.get("Content");
}
It gives me error that arraylist cannot be cast to java.lang.string.
What is wrong here?
If i do it like this:
ArrayList<?> contentArray = new ArrayList<?>();
for(HashMap<?, ?> subTopicsEntry : subTopics){
contentArray = (ArrayList<?>) subTopicsEntry.get("Content");
}
it works
What is the difference ?

First of all Arrays.asList() returns List<String>, not ArrayList<String>.
You have to define your variable as this:
List<String> contentArray = new ArrayList<String>();
But that's not all the problems you have here.

As commenters have noted, you have (probably) misdeclared your Map. Perhaps you mean
ArrayList<String> contentArray = new ArrayList<String>(); // this initializer is unnecessary, btw
for(HashMap<String, ArrayList<String>> subTopicsEntry : subTopics){
contentArray = subTopicsEntry.get("Content"); // Note that a cast is no longer necessary
}
I question whether you really want ArrayLists here, but without seeing the rest of your code it's hard to say.

My answer code is:
package Examples;
import java.util.ArrayList;
import java.util.List;
public class ExampleClass
{
private List<String> _list;
#Override
public String toString() // override default method
{
String temp = "";
for (String s : this._list)
{
temp += (temp.length() == 0 ? "" : ", ") + s;
}
return "ExampleClass: [" + temp + "]";
}
public ExampleClass() // initialize this example class
{
this._list = new ArrayList<>();
this._list.add("Hello!");
this._list.add("Ciao!");
this._list.add("Good morning!");
this._list.add("Good afternoon!");
}
}
/*
// some code for using example
ExampleClass ec = new ExampleClass();
// prints next text to console:
// ExampleClass: [Hello!, Ciao!, Good morning!, Good afternoon!]
System.out.println(ec.toString());
*/
Have a nice day. Yuri

Related

Strange behaviour with ArrayList

I'm in the process of building a basic database using csv files, and i'm currently testing the select function out when i ran into something strange.
private ArrayList<Record> selectField(String selectTerm)
{
Log.log("Selection " + selectTerm,2,"DB_io");
ArrayList<Record> ret = new ArrayList<Record>();
if (titleRow.values.contains(selectTerm))
{
Log.log("Adding values to " + selectTerm);
int ordinal = titleRow.values.indexOf(selectTerm);
Log.log("Ordinal " + ordinal);
List<String> tempList = new ArrayList<String>();
for (Record r : data)
{
List<String> tempList = new ArrayList<String>();
tempList.add(r.values.get(ordinal));
Record s = new Record(tempList);
ret.add(s);
tempList.clear();
}
Log.log("Number of records in ret " + ret.size());
for (Record t : ret)
{
Log.log(t.toString());
}
}
else
{
Log.log("keyField does not contain that field");
return null;
}
Log.log("Values " + ret.toString());
return ret;
}
When i do this, the part where it logs t.ToString() shows the record to be empty, whereas if i log it before tempList.clear(), it shows the record to be containing data like it should.
If i move the tempList declaration into the Record r : data loop, then it works fine and the Record t : ret loop works outputs the contents of the record like it should
Why is this?
Edit : Record class
public class Record
{
List<String> values = new ArrayList<String>();
public Record(List<String> terms)
{
this.values = terms;
}
public Record(String[] s)
{
this.values = Arrays.asList(s);
}
public String toString()
{
return values.toString();
}
}
Your Record instance holds a reference to the ArrayList instance you passed to its constructor. Therefore, when you call tempList.clear(), you clear the same List that your Record instance is holding a reference to.
You shouldn't call tempList.clear(), since you are creating a new ArrayList in each iteration of your loop anyway.
you are referencing object from more than one place and clear method is cleaning object by setting its reference to null:
instead of ret.add(s); you can use ret.add(s.clone());

How to retrieve word after specific word in Java?

I've this kind of String:
{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}
and i want to get a list of all words after cc=.
How can i do it? I'm not very confident with regex stuff.
public static void main(String[] args) {
String input = "aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3";
String[] splitValues = input.split(", ");
Map<String,List<String>> results = new Hashtable<>();
List<String> valueList = null;
// iterate through each key=value adding to the results
for (String a : splitValues) {
// a = "aa=bbbb" etc
String[] keyValues = a.split("=");
// you can check if values exist. This assumes they do.
String key = keyValues[0];
String value = keyValues[1];
// if it is already in map, add to its value list
if (results.containsKey(key)) {
valueList = results.get(key);
valueList.add(value);
} else {
valueList = new ArrayList<>();
valueList.add(value);
results.put(key, valueList);
}
}
System.out.println("cc= values");
valueList = results.get("cc");
// assumes value is in results
for (String a : valueList)
System.out.println(a);
}
Your question is very vague but I am guessing the String is provided as is, like:
String toSearch = "{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}";
By list I am guessing you are referring to the abstract List object and not to an array. Here is a solution:
String toSearch = "{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}";
List<String> result = new ArrayList<String>();
int prevMatch = 0;
while (toSearch.indexOf("cc=", prevMatch+1) != -1) {
result.add(toSearch.substring( // Substring method.
toSearch.indexOf("cc=",prevMatch+1)+3,toSearch.indexOf(",") //Getting correct indexes.
));
prevMatch = toSearch.indexOf("cc=",prevMatch+1);
}
The prevMatch variable ensures that the indexOf("cc=") that will be returned will be the next one occurring in the String. For the above String the returning ArrayList will contain the words "blabla1","blabla2", "blabla3" and whatever else is encountered.

Java 8 shows this error. Local variable itemList defined in an enclosing scope must be final or effectively final

I am writing the code using java 8 but I iterate a List and then find RestaurantOrderBook using category type. and put that List into a Map. it shows this error:
Local variable itemList defined in an enclosing scope must be final or effectively final
Query query = new Query();
String categ = category;
query.addCriteria(Criteria.where("restaurantId").is(restaurantId));
List<RestaurantOrderBook> itemList = new ArrayList<RestaurantOrderBook>();
itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
System.out.println("size : " + itemList.size());
Map<String , List<RestaurantOrderBook>> map = new HashMap<String , List<RestaurantOrderBook>>();
Arrays.asList("TakeAway", "Dining").forEach(e ->{
//Following line throws error:
List<RestaurantOrderBook> list = itemList.stream().filter(a -> !a.getOrderType().isEmpty() && a.getOrderType().equals(e)).collect(Collectors.toList());
map.put(e, list);
});
I have an another situation:
#Override
public EventReportRewardsPoints eventReportRewardsPoints(String organizerId) {
try{
List<Event> listOfEvents = eventRepo.findByOrganizerId(organizerId);
EventReportRewardsPoints eventTransReport = new EventReportRewardsPoints();
Integer soldTics = 0;
Double totalRevenue = 0d;
Integer soldToday = 0;
Integer findTotalAvailableTics = 0;
Integer findTotalQtytics = 0;
for (Event event : listOfEvents) {
List<EventTicket> eventTicket = eventTicketRepo.findByEventId(event.getId());
Integer sumOfAvailabletics = eventTicket.stream()
.mapToInt(EventTicket::getRemainingTickets).sum();
findTotalAvailableTics = findTotalAvailableTics + sumOfAvailabletics;
Integer sumOfQtytics = eventTicket.stream().mapToInt(EventTicket::getQty).sum();
findTotalQtytics = findTotalQtytics + sumOfQtytics;
List<EventTicketBook> listOfEventsTic = eventTicketBookRepository.findByEventId(event.getId());
for (EventTicketBook eventTicketBook : listOfEventsTic) {
Double sumOfSales = eventTicketBook.getTickets().stream().mapToDouble(EventTicket::getPrice).sum();
totalRevenue = totalRevenue + sumOfSales;
Date now = new Date();
System.out.println("create date : " + eventTicketBook.getCreateOn());
/*if(now.compareTo(eventTicketBook.getCreateOn()) == 0){
Integer sumOfSoldToday = eventTicketBook.getTickets().stream().mapToInt(EventTicket::getQty).sum();
soldToday = soldToday + sumOfSoldToday;
}*/
}
}
System.out.println("findTotalQtytics : " + findTotalQtytics);
System.out.println("findTotalAvailableTics : " + findTotalAvailableTics);
soldTics = findTotalQtytics - findTotalAvailableTics;
eventTransReport.setTotalRevenue(totalRevenue);
eventTransReport.setSoldToday(soldToday);
eventTransReport.setTicketsSold(soldTics);
return eventTransReport;
}catch(Exception e ){
e.printStackTrace();
}
return null;
}
How do i achive this using lamda expression.??
You are using itemList within a lambda expression. Therefore it has to be final.
Java 8 introduces the new concept of effectivly final, which means, the compiler checks, if a used variable is final in usage and does not force the developer to explicitly declare it as final.
So if you change your code to
final List<RestaurantOrderBook> itemList = new ArrayList<RestaurantOrderBook>();
you will see, that the compiler gives you an error at:
itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
because you are reasigning itemList. That is why itemList is not effectivly final as well. If you squash these two lines to
List<RestaurantOrderBook> itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
it should work.
Declare your variable itemList final:
final List<RestaurantOrderBook> itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
As noted in the accepted answer by wumpz, the reason is that the variable being used has to be final or effectively final.
I would like to add the reason as to why it is so:
When we write a Lambda expression, we are effectively authoring an anonymous inner class. For Ex:
#FunctionalInterface
interface MyInterface{
public void print();
}
Used in our code as:
public static void main(String[] args) {
int i = 6;
new MyInterface() {
#Override
public void print() {
System.out.println(++i); // Remove ++ to resolve error
}
}.print();
}

How to print a value from a Hashmap with a ArrayList

I am working on a piece of code which has a Hashmap. This hashmap has a string as key and an arraylist as value. I populate arraylist the with values I'm fetching using a DQL. I've three attributes for many users. Then putting the value into the hashmap. What I want is to iterate the Hashmap and fetch the set of 3 attritubes for 1 user. Let me provide the code below
package com;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import xtrim.util.i;
import com.documentum.com.DfClientX;
import com.documentum.com.IDfClientX;
import com.documentum.fc.client.DfQuery;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfCollection;
import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfLoginInfo;
public class Adlookup {
IDfSessionManager sessionMrg = null;
IDfSession session=null;
IDfClient dfclient = null;
IDfClientX clientX = new DfClientX();
IDfCollection total = null;
int j;
int flag = 0;
WriteToExcel ex = new WriteToExcel();
public void LookupReport(String docbaseName, String username, String password) throws DfException, IOException
{
dfclient = clientX.getLocalClient();
String Docbase = docbaseName;
IDfLoginInfo loginInfo = new DfLoginInfo();
loginInfo.setUser(username);
loginInfo.setPassword(password);
sessionMrg = dfclient.newSessionManager();
sessionMrg.setIdentity(Docbase, loginInfo);
session = sessionMrg.getSession(Docbase);
System.out.println("connection created for adlookup");
String query = Getquery();
IDfQuery dql = new DfQuery();
dql.setDQL(query);
total = dql.execute(session, IDfQuery.DF_EXEC_QUERY);
System.out.println("all good for lookup");
//String[] columnNames = new String[] { "User Name","User Login Name","Email"};
List<String> lstValues = new ArrayList<String>();
Map<Integer, ArrayList<String>> myMap = new HashMap<Integer, ArrayList<String>>();
while (total.next())
{
lstValues.add(total.getString("uname")+","+total.getString("loginname")+","+total.getString("uadd"));
myMap.put(flag, (ArrayList<String>) lstValues);
flag++;
System.out.println("Flag value: " +flag);
// lstValues.clear();
}
Set setofKeys = myMap.keySet();
Iterator itr = setofKeys.iterator();
while(itr.hasNext())
{
Integer key = (Integer) itr.next();
ArrayList<String> value = myMap.get(key);
System.out.println("\nResult :"+value);
}
}
private String Getquery() {
// TODO Auto-generated method stub
String query = "select user_name as uname, user_login_name as loginname, user_address as uadd from dm_user dmu, dm_dbo.MV_V_MIDAS_MERCK_PRSN1 dma where upper(dmu.user_login_name)=upper(dma.isid) and dmu.user_state=0 and directory_display_ind='I'";
return query;
}
}
I'm getting output like this
Result :
[Sayre,Joseph,sayrej,joseph.sayre#abc.com, Kapoor,Rohit,kapoorro,rohit.kapoor#abc.com, Pineiros-Vallejo, Miguel,pineirom,rajendra.baxi#abc.com]
Result :[Sayre,Joseph,sayrej,joseph.sayre#abc.com, Kapoor,Rohit,kapoorro,rohit.kapoor#abc.com, Pineiros-Vallejo, Miguel,pineirom,rajendra.baxi#abc.com]
Result :[Sayre,Joseph,sayrej,joseph.sayre#abc.com, Kapoor,Rohit,kapoorro,rohit.kapoor#abc.com, Pineiros-Vallejo, Miguel,pineirom,rajendra.baxi#abc.com]
but I want something like this :
Result : Sayre,Joseph,sayrej,joseph.sayre#abc.com
Result : Kapoor,Rohit,kapoorro,rohit.kapoor#abc.com
Result : Pineiros-Vallejo, Miguel,pineirom,rajendra.baxi#abc.com
Also I need to print this values in an excelsheet.
Any kind of help will appreciated.
If the content of the ArrayList are attributes of a user, then why don't you create a class UserAttributes having fields to store the values and overrides toString() to output them?
Instead of using toString() on the ArrayList itself, iterate over its contents and print the individual members. Add another loop inside the while(itr.hasNext()) loop.
Use advanced for to display the String value like below,
while(itr.hasNext())
{
Integer key = (Integer) itr.next();
ArrayList<String> value = myMap.get(key);
System.out.print("\nResult : ");
for(String strValue:value){
System.out.println(strValue + ",");
}
}
Thanks
Raju
I'd create an object "user" with fields for each entry:
lstValues.add(total.getString("uname")+","+total.getString("loginname")+","+total.getString("uadd"));
to
lstValues.add(new User(total.getString("uname"), total.getString("loginname"), total.getString("uadd")));
Then override toString() inside the User object.
Tip:
You can also use map.entrySet() to iterate.
Your code:
Set setofKeys = myMap.keySet();
Iterator itr = setofKeys.iterator();
while(itr.hasNext())
{
Integer key = (Integer) itr.next();
ArrayList<String> value = myMap.get(key);
System.out.println("\nResult :"+value);
}
My Code:
Map<Integer, User> map = new HashMap<>();
for( Entry<Integer, User> entry : map.entrySet() ) {
entry.getKey();
entry.getValue(); // the user object you want
}
Instead of
while(itr.hasNext())
{
Integer key = (Integer) itr.next();
ArrayList<String> value = myMap.get(key);
System.out.println("\nResult :"+value);
}
use this
while (total.next) {
System.out.println("\nResult :"
+ itr.getString("uname") + ", "
+ itr.getString("loginname") + ", "
+ itr.getString("uadd") );
}
EDIT: switched from using itr object to total object. I see you are using IDfCollection total for adding some flag which you don't use later anywhere. Lose everything and just loop through collection total. Your code is big mixture of your temporarily ideas that survived when you changed your mind. Change your code. :)

For-Each Loop Incompatible Types

I'm working on a project that creates a virtual database for films. I have two classes: MovieEntry (for the individual movie entry) and MovieDatabase (the larger class that contains the database and allows for additions, etc.) I'm getting a few errors, the first of them being that in the searchTitle method it says that Database is of an incompatible type. Can anyone tell me how to do these for-each loops? I read the book and I thought the ArrayList was supposed to go there but apparently not.
**import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;
public class MovieDatabase
{
private ArrayList<MovieEntry> Database = new ArrayList<MovieEntry>();
public MovieDatabase(){
ArrayList<MovieDatabase> Database = new ArrayList<MovieDatabase>(0);
}
public int countTitles() throws IOException{
Scanner fileScan;
fileScan = new Scanner (new File("movies.txt"));
int count = 0;
String movieCount;
while(fileScan.hasNext()){
movieCount = fileScan.nextLine();
count++;
}
return count;
}
public void addMovie(MovieEntry m){
Database.add(m);
}
public ArrayList<MovieEntry> searchTitle(String substring){
for (String title : Database)
System.out.println(title);
return null;
}
public ArrayList<MovieEntry> searchGenre(String substring){
for (String genre : Database)
System.out.println(genre);
return null;
}
public ArrayList<MovieEntry> searchDirector (String str){
for (String director : Database)
System.out.println(director);
return null;
}
public ArrayList<MovieEntry> searchYear (int yr){
ArrayList <String> yearMatches = new ArrayList<String>();
for (String s : Database)
s.getYear();
if(yearMatches.contains(y) == false){
yearMatches.add(y);
}
return yearMatches;
}
public ArrayList<MovieEntry> searchYear(int from, int to){
ArrayList <String> Matches = new ArrayList<String>();
for(Student s : movies);
Matches.add();
return Matches;
}
public void readMovieData(String movies){
String info;
try{
Scanner fileReader = new Scanner(new File(movies));
Scanner lineReader;
while(fileReader.hasNext()){
info = fileReader.nextLine();
lineReader = new Scanner(info);
lineReader.useDelimiter(":");
String title = lineReader.next();
String director = lineReader.next();
String genre = lineReader.next();
int year = lineReader.nextInt();
}
}catch(FileNotFoundException error){
System.out.println("File not found.");
}catch(IOException error){
System.out.println("Oops! Something went wrong.");
}
}
public int countGenres(){
String g;
ArrayList <String> gList = new ArrayList<String>();
for(Student s : movies){
String g = s.getGenre();
if(gList.contains(g) == false){
gList.add(g);
}
return gList.size();
}
}
public int countDirectors(){
ArrayList <String> dList = new ArrayList<String>();
for(Student s : movies){
String d = s.getDirector();
if(dList.contains(d) == false){
dList.add(d);
}
return dList.size();
}
}
public String listGenres(){
ArrayList <String> genreList = new ArrayList<String>();
}
}**
The type of the foreach variable (String, in the case of the loop in your searchTitle method) must be compatible with the type parameter (MovieEntry) of the parameterized type (ArrayList<MovieEntry>). This is clearly not the case. The following foreach loop would work:
for (MovieEntry title : Database) {
System.out.println(title);
}
Please consider following the convention of using lowercase names for fields, i.e. call your ArrayList<MovieEntry> with a name such as database instead of Database.
Well
for (Type obj : Collection) {...}
works only if the collection holds elements of type Type. This practically in your case means:
for (MovieDatabase database : Database) {...}
will work because Database is ArrayList holding the type MovieDatabase:
ArrayList<MovieDatabase> Database= new ArrayList<MovieDatabase>();
if you want to loop over titles in database you have to provide a method that gives back the list of Strings of titles, for example
public ArrayList<String> getTitles() {...}
....
for (String title : Database.getTitles()) {...}
Your Database property (should be database, lowercase), is of type:
ArrayList<MovieDatabase>
And you're trying to iterate over it using a String as the element type.
Your foreach should be:
for(MovieDatabase element: Database){
....
}
your for-each loop should look something like this (this is just an example so you'll have to adapt it for yours)
ArrayList<MovieEntry> list = new ArrayList<MovieEntry>();
...
for(MovieEntry m : list) {
...
}
an ArrayList is a valid thing to loop over but in your case you are trying to get Strings when your list doesn't hold Strings then you are calling methods on those Strings that String doesn't support. You have to use the right type for each list.
change
private ArrayList<MovieEntry> Database = new ArrayList<MovieEntry>();
public MovieDatabase(){
ArrayList<MovieDatabase> Database = new ArrayList<MovieDatabase>(0);
}
to
private ArrayList<MovieEntry> Database;;
public MovieDatabase(){
Database = new ArrayList<MovieDatabase>(0);
}

Categories

Resources